观察变量并进行更改

时间:2014-08-15 07:35:07

标签: angularjs watch

在AngularJS中,我有一个监视范围变量的指令。当变量包含某些数据时,我需要稍微更改该变量。问题是,当我更改变量时,我的$watch再次被触发。所以我最终会在一个循环中结束。

scope.$watch('someVar', function(newValue, oldValue) {
    console.log(newValue);
    scope.someVar = [Do something with someVar];
});

这会再次触发$watch,这是有道理的。但我确实需要一种方法来改变观察变量。有没有办法做到这一点?

5 个答案:

答案 0 :(得分:25)

当使用$scope.$watch监视变量的变化时,angular会检查参考是否已更改。如果有,则执行$watch处理程序以更新视图。

如果您计划更改$ watch处理程序中的范围变量,它将触发无限$ digest循环,因为范围变量引用每次调用时都会更改。

解决无限摘要问题的诀窍是使用 angular.copy 保留 $watch处理程序中的引用(docs):

scope.$watch('someVar', function(newValue, oldValue) {
    console.log(newValue);
    var someVar = [Do something with someVar];

    // angular copy will preserve the reference of $scope.someVar
    // so it will not trigger another digest 
    angular.copy(someVar, $scope.someVar);

});

注意:此技巧仅适用于对象引用。它不适用于原语。

通常,在自己的$watched侦听器中更新$watch变量不是一个好主意。但是,有时它可能是不可避免的。

答案 1 :(得分:13)

内部函数使用 if 条件以避免连续循环

scope.$watch('someVar', function(newValue, oldValue) {
   if(newValue!==oldValue) {
    console.log(newValue);
    scope.someVar = [Do something with someVar];
   } 
});

答案 2 :(得分:2)

这是脏检查的工作原理。每当$scope上的某些内容发生变化时,Angular都会旋转附加到范围内的所有内容,并且它会继续这样做,直到不再有更改。

如果你想做类似的事情,你必须确保你的$watch功能是幂等的。您必须同时查看newValueoldValue,并确定您已在此$digest循环中将更改应用于变量。如何做到这一点取决于您对someVar所做的更改。

一般来说,在监视功能中更改监视变量遗憾的是不是一个好主意。

答案 3 :(得分:2)

您可以使用bool变量管理它

$scope.someVarChanged = false;

scope.$watch('someVar', function(newValue, oldValue) {
    console.log(newValue);
    $scope.someVarChanged = !$scope.someVarChanged!;
    if($scope.someVarChanged) {            
        scope.someVar = [Do something with someVar];
    }
});

答案 4 :(得分:1)

是的,你可以像这样取消它

var wathcer = scope.$watch('someVar', function(newValue, oldValue) {
    console.log(newValue);
    scope.someVar = [Do something with someVar];

});
wathcer(); // clear the watch