Watch variable and change it

让人想犯罪 __ 提交于 2019-11-28 22:30:20

问题


In AngularJS I have a directive that watches a scope variable. When the variable contains certain data then I need to alter that variable a bit. The problem is that when I change the variable that my $watch is triggered again. So I end up in a continuous loop.

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

This keeps triggering $watch again, which makes sense. But I do need a way to change the watched variable. Is there a way to do this?


回答1:


When a variable is watched for changes using $scope.$watch, angular checks if the reference has changed. If it has, then the $watch handler is executed to update the view.

If you plan on changing the scope variable within the $watch handler, it will trigger an infinite $digest loop because the scope variable reference changes every time that it is called.

The trick to getting around the infinite digest issue is to preserve the reference inside your $watch handler using angular.copy (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);

});

Note: This trick only works for object references. It will not work with primitives.

In general, its not a good idea to update a $watched variable within its own $watch listener. However, sometimes it may be unavoidable.




回答2:


Inside function use if condition to avoide continues for loop

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



回答3:


This is how dirty-checking works. Every time something on the $scope changes Angular will spin through everything that is attached to the scope and it will keep doing so untill there are no more changes.

If you want to do something like that, you will have to make sure that your $watch function is idempotent. You will have to look at both newValue and oldValue and figure out wether you've already applied the changes to your variable in this $digest loop. How you can do that depends a bit on what kind of changes you're doing to someVar.

Generally speaking, changing a watched variable in a watch-function is unfortunately not a good idea.




回答4:


you can manage it using a bool variable

$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];
    }
});



回答5:


yes you can cancel it like this

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

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


来源:https://stackoverflow.com/questions/25322780/watch-variable-and-change-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!