AngularJS/ng-grid - Updating array with splice doesn't updates UI

后端 未结 3 1322
独厮守ぢ
独厮守ぢ 2020-12-18 05:37

I am trying to update ng-grid with array splice. I have a plunk here.

Add button adds new row. Update button updates

相关标签:
3条回答
  • 2020-12-18 06:11

    I am using ui-grid v3.0.0 (from an April 2015 unstable build). I found this post and wanted to show others how I refreshed my grid after I removed a row from the grid data object using splice:

    // Remove the row and refresh the grid.
    $scope.myData.splice(rowIndex, 1);
    $scope.gridApi.grid.refresh(true);
    

    where my gridApi scope variable was set with this function:

    $scope.gridOptions.onRegisterApi = function(gridApi){
        $scope.gridApi = gridApi;
    }
    
    0 讨论(0)
  • 2020-12-18 06:14

    That's because data $watcher in ng-grid (incorrectly) compares the data object for reference, instead on object equality. You might remedy this by setting the third parameter to true in data $watch function (line 3128):

    $scope.$parent.$watch(options.data, dataWatcher, true);
    

    Plunker

    0 讨论(0)
  • 2020-12-18 06:26

    UPDATE (2015-04-10)

    Angular has improved their code base (1.4.0), try the $scope.$watchCollection method first, and see if it works for you. (Link)

    ANSWER

    If you don't feel like hacking into a 3rd party library, you could add the hack in your code using:

    $scope.updateData = function() {
      var data = angular.copy($scope.myData);
      data.splice(data.length - 1, 1, {name: 'UPDATED', age: '4'})
      $scope.myData = data;
    };
    

    plunkr

    As @Stewie mentions, the problem is that for performance reasons ngGrid compares the data object superficially, and in the case of arrays, this is by reference. ngGrid also compares by the array length, so if the array doesn't change it's length the grid wont' get updated.

    This solution creates a copy of the array (different place in memory) so that when angularjs $watcher checks for changes it will find a different object and run the ngGrid update callback.

    NOTE: Because this solution creates a copy of the data array on every call to updateData, it could lead to performance problems if your data is too big, also Javascript doesn't have a great garbage collection.

    Old Incorrect Answer:

    $timeout(angular.noop, 0);

    This simply sets a timeout to trigger a $scope.$apply() after the current one is done. A way of forcing a dirty check.

    0 讨论(0)
提交回复
热议问题