Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

Issue when reloading data with two tables #282

Closed
davidda opened this issue Apr 20, 2015 · 5 comments
Closed

Issue when reloading data with two tables #282

davidda opened this issue Apr 20, 2015 · 5 comments
Labels
Milestone

Comments

@davidda
Copy link

davidda commented Apr 20, 2015

In my application I encountered a very weird behavior. I have two views, each with one datatable. If only one of the views is accessed, no problem occurs. If you however navigate to the other view and then back to the first view (so the second table is instantiated), it is no longer possible to update any datatable.

What happens in this case is that the system tries to process the new rows with the columnDefs "data" function of the OTHER table respectively!

I was able to create a Plunker example of this behavior: http://plnkr.co/edit/ZvNyJV81i21tZhp4Bz9u
Steps to recreate:

  • Click "Load" --> no error
  • Click "View 2", then "View 1", then click "Load" --> error!

I don't know if the error depends on it being two seperate views or if it would occurr as well if the tables are on the same page.

@mathewbergt
Copy link
Contributor

Looks like the call to getLast isn't actually returning the last DTInstance because the directive hasn't yet initialized the datatable instance, since ui-router likely runs the controller before the template is rendered. So immediately calling DTInstances.getLast().then(... and setting ctrl1.dtInstance = dtInstance will always result in it being set to the previous DTInstance. Instead of setting it immediately on load of Route1Ctrl, you could try the following:

this.load = function() {
    DTInstances.getLast().then(function(dtInstance) {
        dtInstance.changeData(function() {
            return $q(function(resolve) { resolve([{ a: 1 }, { a: 2 }, { a: 3 }]); });
        });
    });
};

It appears that each time ui-router changes state and re-renders the template, a new DTInstance is pushed onto DTInstances. I'm guessing this is not the desired behavior.

@davidda
Copy link
Author

davidda commented Apr 21, 2015

Thank you! That was indeed the issue. I now understand what is happening.

I'm not sure how getLast() decides when to resolve the promise, but it seems to happen as soon as any datatable is present in DTInstances - which is really the best a function with this name can do. That's why it works for the view loaded first but not for the second view.

I think it is expected that a new instance is created when the template is re-rendered, because a new datatable directive is instantiated. What I an wondering though is: Why is the "old" instance still present? Shouldn't it be destructed if the DOM table gets unloaded? If that was happening I suppose getLast() would behave as expected.

@l-lin
Copy link
Owner

l-lin commented Apr 23, 2015

Yeah, it's not the desired behaviour. Thanks for noticing it 👍

@l-lin l-lin added the bug label Apr 23, 2015
@l-lin l-lin added this to the v0.4.3 milestone Apr 24, 2015
l-lin added a commit that referenced this issue Apr 24, 2015
@l-lin
Copy link
Owner

l-lin commented Apr 24, 2015

Fixed. See the change in the modified plnkr.

However, this fix is not really satisfactory. In order to fix this issue, I had to "revert" the enhancement #234 (possibility to call DTInstances.getLast() and DTInstances.getList() everywhere). To preserve the previous behaviour, I had to use a fallback when fetching the dtInstances in case there are no new datatables.
In other words, I added a timeout (1 second timeout) in the promises DTInstances.getLast() and DTInstances.getList() after which they return their previous value. 😞

The reason for this fallback is because I don't know if DTInstances.getXXXX() is called before DTInstances.register() or DTInstances.register() is called before DTINstances.getXXX().

@l-lin l-lin closed this as completed Apr 24, 2015
@ssotomayor
Copy link

Any workaround this? Same as the first guy, if you navigate to other view and then back to the first view the event ".on('click" for that cell stops happening.

MyApp.controller('MainControllerNewPartial',["$scope", "DTOptionsBuilder", "DTColumnBuilder", "MainService", "DTInstances", function($scope, DTOptionsBuilder, DTColumnBuilder, MainService, DTInstances) {

  var ctrlNew = this;
  ctrlNew.dtOptions = DTOptionsBuilder.newOptions()
    .withOption('ajax', {
      url: '/data.json',
      type: 'GET'
    })

    .withDataProp('data')
    .withPaginationType('full_numbers');

  ctrlNew.dtColumns = [
    DTColumnBuilder.newColumn(null).withTitle(' ').renderWith(function(){return "<i class='fa fa-plus-square'></i>"}),
    DTColumnBuilder.newColumn('type').withTitle(' '),
    DTColumnBuilder.newColumn(null).withTitle('Action').renderWith(function(){return "<button type='button' ng-click='showCase.approveTransaction()' class='btn btn-success transaction-actions'><i class='fa fa-check'></i></button> <button type='button' ng-click='showCase.removeTransaction($index)' class='btn btn-danger transaction-actions'><i class='fa fa-close'></i></button>"}),
    DTColumnBuilder.newColumn('trans_id').withTitle('Trans ID'),
    DTColumnBuilder.newColumn('status').withTitle('Status'),
    DTColumnBuilder.newColumn('site_tag').withTitle('Site Tag')
...
  ];

  DTInstances.getLast().then(function (dtInstance) {
    ctrlNew.dtInstance = dtInstance;

// this event is executed only once, but when i change views and come back, it stops firing, no error.
    ctrlNew.dtInstance.dataTable.on( 'click', 'tr td .btn-success', function () {
      var tr = $(this).closest('tr');
      var row = dtInstance.DataTable.row( tr );
      console.log(row.data());
    });

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

4 participants