最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJSng-grid - Updating array with splice doesn't updates UI - Stack Overflow

programmeradmin1浏览0评论

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

Add button adds new row. Update button updates last item in the array.

  1. Select a row & press update button. Nothing happens.
  2. Press add button. Now UI gets updated with new element & as well as the previously updated element.
  3. Same behavior gets repeated again & again.

I tried $scope.$apply. I get:

“Error: $apply already in progress”

I even tried by placing $scope.$apply block inside a setTimeout call. Again the same error!

Any pointers!

Thanks!

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

Add button adds new row. Update button updates last item in the array.

  1. Select a row & press update button. Nothing happens.
  2. Press add button. Now UI gets updated with new element & as well as the previously updated element.
  3. Same behavior gets repeated again & again.

I tried $scope.$apply. I get:

“Error: $apply already in progress”

I even tried by placing $scope.$apply block inside a setTimeout call. Again the same error!

Any pointers!

Thanks!

Share Improve this question edited May 29, 2014 at 19:09 CommunityBot 11 silver badge asked Jul 8, 2013 at 14:45 user405398user405398
Add a comment  | 

3 Answers 3

Reset to default 15

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

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.

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)

  1. 暂无评论