Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async loading of datasource and binding not working with Angular #180

Open
mathiasconradt opened this issue Aug 31, 2016 · 2 comments
Open

Comments

@mathiasconradt
Copy link

mathiasconradt commented Aug 31, 2016

I have a handsontable where I load the data asynchronously, which I simulate with a delay of 3 seconds in my example.

This is the table, configured via settings="ctrl.settings":

  <hot-table col-headers="true" settings="ctrl.settings">
    <hot-column data="id" title="'ID'" read-only></hot-column>
    <hot-column data="name.first" title="'First Name'"></hot-column>
    <hot-column data="name.last" title="'Last Name'"></hot-column>
    <hot-column data="address" title="'Address'"></hot-column>
    <hot-column data="price" title="'Price'" type="'numeric'" format="'$ 0,0.00'"></hot-column>
    <hot-column data="isActive" title="'Is Active'" type="'checkbox'" checked-template="'Yes'" unchecked-template="'No'"></hot-column>
  </hot-table>

and the controller like this, where you can see that I set the data source like this data: _this.delayedData,:

function MainCtrl(dataFactory) {
  var _this = this;  
  _this.data = dataFactory.generateArrayOfObjects();  
  _this.delayedData = []; // this will be filled with a delay

  this.settings = {
    // data: _this.data,
    data: _this.delayedData,
    dataSchema: this.data
  }
  this.columns = [
    {
      data: 'id',
      title: 'ID',
      readOnly: true
    },
    {
      data: 'price',
      title: 'Price',
      readOnly: false
    }
  ];


  // here the data is loaded with a delay of 3 seconds
  // and the table is then rendered again 
  setTimeout(function(){ 
      _this.delayedData = _this.data; 
      console.log('Setting delayed values ' + JSON.stringify(_this.delayedData));    

      // get instance of table and re-render
      var hotDiv = angular.element($('hot-table'));
      if (hotDiv!==undefined && hotDiv.isolateScope()!==undefined) {
          var hotInstance = hotDiv.isolateScope().hotInstance;
          if (hotInstance!==undefined) {
              hotInstance.render();
              console.log("=========================");
              console.log('Rendered but not showing in the table! Why?');
              console.log("========================="); 
          }
      }    

  }, 3000);

}

JS Bin: http://jsbin.com/daniyov/edit?html,js,console,output

So the data is being loaded a bit delayed after the table has been defined in the controller. According to the handsontable documentation, the render() method of the table should be called whenever the data changes, like in this example of the documentation.

I do see the "Render!" output in the console, so this code does get called and the data is being loaded into _this.delayedData, however, the items don't show up in the table.

@mathiasconradt mathiasconradt changed the title Data not showing when binding via "settings:data" in controller instead of "datarows" in view Data not showing when binding via "settings={data:...}" in controller instead of "datarows" in view Aug 31, 2016
@mathiasconradt mathiasconradt changed the title Data not showing when binding via "settings={data:...}" in controller instead of "datarows" in view Delayed, async loading of datasource and re-rendering not working Sep 1, 2016
@mathiasconradt
Copy link
Author

mathiasconradt commented Sep 1, 2016

===== UPDATE =====

I updated my sample at JS Bin: http://jsbin.com/daniyov/edit?html,js,console,output and did some more debugging.

It seems that the data source that I assign to my table does not really hold a reference to the object I assigned.

The two log outputs show different values:

// this has value 10:
console.log('Table source data length: ' + hotInstance.getSourceData().length);
// this has value 0:
console.log('delayedData length: ' + _this.delayedData.length); 

even though _this.delayedData is the data source of my table, and from my understanding it's bound by reference, set via:

this.settings = {
  data: _this.delayedData
}

A similar example that I created, but without Angular / Angular directive, works fine this way: http://jsfiddle.net/mathiasconradt/L4z5pbgb/ Just with Angular / ngHandsontable, I cannot get it to work.

@mathiasconradt
Copy link
Author

I found a workaround by updating the settings again like this before re-rendering the table, but I don't understand why this would be needed.
There should be a reference to _this.delayedData at all time by the table.

              // THIS IS THE WORKAROUND I NOW FOUND. I JUST ASSIGN THE DATA SOURCE
              // AGAIN, BUT WHY IS THAT NEEDED?
              hotInstance.updateSettings({
                  data: _this.delayedData,
              });

              hotInstance.render(); 

Looks like a bug to me.

@mathiasconradt mathiasconradt changed the title Delayed, async loading of datasource and re-rendering not working Async loading of datasource and binding not working with Angular Sep 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants