简体   繁体   中英

How to dynamically create Angular watches inside a loop

I want to be able to dynamically create angular watches on one or more model attributes. To that end I've tried something such as the following:

var fields = ['foo', 'bar'];
for (var i=0, n=fields.length; i<n; i++) {
    $scope.$watch('vm.model.' + fields[i], function(newValue, oldValue) {
        console.log(fields[i]); //always 'bar'
        //logic that was not giving the expected results
    });
}

However this was always working with the last element of the array on every iteration of the loop. I've seen this behavior when working with asynchronous code before, could that be at play here. If so, how to solve?

This is because "after a watcher is registered with the scope, the listener fn is called asynchronously (via $evalAsync ) to initialize the watcher" -- see the documentation and search for the first instance of $watch in the page.

With that in mind it should be easy to resolve by delegating to another function on each iteration of the loop, as follows:

var fields = ['foo', 'bar'];
for (var i=0, n=fields.length; i<n; i++) {
    createWatch(fields[i]);
}
function createWatch(field) {
    $scope.$watch('vm.model.' + field, function(newValue, oldValue) {
        console.log(field); //'foo' on first iteration, 'bar' on next
        //logic that should now give the expected result
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM