1

我对观察者功能有一个奇怪的问题:

$scope.$watch('builder.editItemForm.quantity',function(newValue,oldValue){
    if(newValue !== oldValue){
        if(newValue % 2 == 0){
            builder.editItemForm.quantity = newValue;
        } else {
            builder.editItemForm.quantity = oldValue;
        }
    }
});

我收到此错误为:

Error: $rootScope:infdig Infinite $digest Loop

10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [["builder.editItemForm.quantity;     newVal: 1; oldVal: undefined"],["builder.editItemForm.quantity; newVal: undefined; oldVal: 1"],["builder.editItemForm.quantity; newVal: 1; oldVal: undefined"],["builder.editItemForm.quantity; newVal: undefined; oldVal: 1"],["builder.editItemForm.quantity; newVal: 1; oldVal: undefined"]]

https://docs.angularjs.org/error/$rootScope/infdig?p0=10&p1=%5B%5B%22builder.editItemForm.quantity;%20newVal:%201;%20oldVal:%20undefined%22%5D,%5B%22builder.editItemForm.quantity;%20newVal:%20undefined;%20oldVal:%201%22%5D,%5B%22builder.editItemForm.quantity;%20newVal:%201;%20oldVal:%20undefined%22%5D,%5B%22builder.editItemForm.quantity;%20newVal:%20undefined;%20oldVal:%201%22%5D,%5B%22builder.editItemForm.quantity;%20newVal:%201;%20oldVal:%20undefined%22%5D%5D

我不确定如何避免这种情况。谁能帮我吗?

4

2 回答 2

0

因为您正在更改手表内的值builder.editItemForm.quantity,它将再次运行摘要循环并在值更改时始终触发手表。在您的情况下,您正在改变手表内部的价值,这将陷入无限循环。

描述

当应用程序的模型变得不稳定并且每个 $digest 循环触发状态更改和后续的 $digest 循环时,就会发生此错误。Angular 会检测到这种情况并防止无限循环导致浏览器无响应。

例如,可以通过在路径上设置监视并随后在值更改时更新相同的路径来发生这种情况。

$scope.$watch('foo', function() {
  $scope.foo = $scope.foo + 1;
});

参考文档 https://docs.angularjs.org/error/$rootScope/infdig

于 2015-07-08T11:20:40.937 回答
0

一种解决方案是通过手表并在设置数量后尝试注销手表。它会工作一次。另一件事是使用 ng-model-options getterSetter,它的作用与您的 watch 事件相同。

1)您可以在某些情况下取消注册观看事件。在您的控制器中:

$scope.$watch('updated', function(newValue,oldValue){
      $scope.stop();
});
$scope.stop = $scope.$watch('builder.editItemForm.quantity',function(newValue,oldValue){
        if(newValue !== oldValue){
            if(newValue % 2 == 0){
                builder.editItemForm.quantity = newValue;
                $scope.updated = true;
            }
            else
            {
                builder.editItemForm.quantity = oldValue;
                $scope.updated = true;
            }
        }
    });

$scope.$watch 返回函数,当被调用时,停止观看,这称为注销。它在这里仍然是重​​复的,但可能会起作用。

另一个更通用的解决方案是使用 ng-model-options getter 和 setter。在您看来使用:

ng-model="quantity" ng-model-options="{ getterSetter: true; }"

并在控制器中定义 getter 和 setter

于 2015-07-08T11:38:02.167 回答