AngularJS / ng-grid - 使用splice更新数组不会更新UI

时间:2013-07-08 14:45:16

标签: javascript angularjs angular-ui ng-grid

我正在尝试使用数组splice更新 ng-grid 。  我有一个强烈的 here

添加按钮添加新行。更新按钮更新阵列中的最后一项。

  1. 选择一行&按更新按钮。什么都没发生。
  2. 按添加按钮。现在,用新元素&更新UI以及之前更新的元素。
  3. 同样的行为再次重演&试。
  4. 我试过了$scope.$apply。我明白了:

      

    “错误:$申请已在进行中”

    我甚至尝试将$scope.$apply阻止放在setTimeout来电中。同样的错误!

    任何指针!

    谢谢!

3 个答案:

答案 0 :(得分:15)

那是因为ng-grid中的数据$ watcher(错误地)比较了数据对象以供参考,而不是对象相等。您可以通过在data $watch function(第3128行)中将第三个参数设置为true来解决此问题:

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

Plunker

答案 1 :(得分:4)

更新(2015-04-10)

Angular已经改进了他们的代码库(1.4.0),首先尝试$scope.$watchCollection方法,看看它是否适合你。 (Link

<强> ANSWER

如果您不想侵入第三方库,可以使用以下代码在代码中添加hack:

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

plunkr

正如@Stewie所提到的,问题在于性能原因ngGrid表面上比较数据对象,而在数组的情况下,这是引用。 ngGrid也比较数组长度,因此如果数组没有改变它的长度,网格将不会更新。

此解决方案创建数组的副本(内存中的不同位置),以便当angularjs $watcher检查更改时,它将找到另一个对象并运行ngGrid更新回调。

注意:因为此解决方案会在每次调用updateData时创建数据数组的副本,如果您的数据太大,可能会导致性能问题,Javascript也不会有一个很棒的垃圾收集。

旧错误答案:

<击> $timeout(angular.noop, 0);

<击>

这只是设置一个超时,在当前完成后触发$scope.$apply()。一种强迫检查的方法。

答案 2 :(得分:0)

我正在使用ui-grid v3.0.0(来自2015年4月的不稳定版本)。我找到了这篇文章,并希望向用户展示在使用splice从网格数据对象中删除一行后如何刷新网格:

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

我的gridApi范围变量是使用此函数设置的:

$scope.gridOptions.onRegisterApi = function(gridApi){
    $scope.gridApi = gridApi;
}