我正在尝试使用 array更新ng-gridsplice
。我在这里有一个笨蛋。
添加按钮添加新行。更新按钮更新数组中的最后一项。
- 选择一行并按更新按钮。没发生什么事。
- 按添加按钮。现在 UI 使用新元素和之前更新的元素进行更新。
- 同样的行为一次又一次地重复。
我试过了$scope.$apply
。我得到:
“错误:$apply 已经在进行中”</p>
我什至尝试在通话中放置$scope.$apply
块。setTimeout
再次出现同样的错误!
任何指针!
谢谢!
这是因为 ng-grid 中的 data $watcher (错误地)比较数据对象以供参考,而不是对象相等性。您可以通过在data $watch 函数(第 3128 行)中将第三个参数设置为 true 来解决此问题:
$scope.$parent.$watch(options.data, dataWatcher, true);
更新 (2015-04-10)
Angular 改进了他们的代码库(1.4.0),$scope.$watchCollection
先试试这个方法,看看它是否适合你。(链接)
回答
如果您不想侵入 3rd 方库,可以使用以下方法在代码中添加 hack:
$scope.updateData = function() {
var data = angular.copy($scope.myData);
data.splice(data.length - 1, 1, {name: 'UPDATED', age: '4'})
$scope.myData = data;
};
正如@Stewie 所提到的,问题在于出于性能原因ngGrid
,从表面上比较数据对象,对于数组,这是通过引用进行的。ngGrid
还按数组长度进行比较,所以如果数组不改变它的长度,网格就不会更新。
此解决方案创建数组的副本(内存中的不同位置),以便当 angularjs$watcher
检查更改时,它将找到不同的对象并运行ngGrid
更新回调。
注意:因为这个解决方案在每次调用时都会创建一个数据数组的副本,updateData
如果你的数据太大,它可能会导致性能问题,而且 Javascript 也没有很好的垃圾收集。
老错误答案:
$timeout(angular.noop, 0);
这只是设置超时以$scope.$apply()
在当前完成后触发 a 。一种强制执行脏检查的方法。
我正在使用 ui-grid v3.0.0(来自 2015 年 4 月的不稳定版本)。我找到了这篇文章,并想向其他人展示我在使用拼接从网格数据对象中删除一行后如何刷新我的网格:
// 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;
}