In angular if I register watch events dynamically (in my case in a for loop), the watch does not work. Please take a look at a fiddle. Any ideas?
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $parse) {
// 1. binding watch inside loop (doesn't work):
$scope.aaa = 1;
$scope.bbb = 2;
$scope.dependsOn = [
function () { return $scope.aaa; },
function () { return $scope.bbb; }
];
for (var i = 0; i < $scope.dependsOn.length; i++) {
$scope.$watch(
function () {
return $scope.dependsOn[i];
},
function (newVal) {
if (newVal !== undefined) {
console.log("doesn't work");
}
}
);
}
$scope.aaa = 5;
$scope.bbb = 6;
// binding watch not inside loop (works):
$scope.ccc = 1;
$scope.ddd = 2;
$scope.dependsOn = [
function () { return $scope.ccc; },
function () { return $scope.ddd; }
];
$scope.$watch(
function () {
return $scope.dependsOn[0];
},
function (newVal) {
if (newVal !== undefined) {
console.log("works");
}
}
);
$scope.$watch(
function () {
return $scope.dependsOn[1];
},
function (newVal) {
if (newVal !== undefined) {
console.log("works");
}
}
);
$scope.ccc = 5;
$scope.ddd = 6;
}
fiddle
The problem you are experiencing is because you are capturing the variable i
in a closure. Then i
gets incremented to the value 2 and drops out of the loop, each of your delegates will have 2 as their i
value upon actually executing the delegate.
Demonstrates: http://jsfiddle.net/df6L0v8f/1/ (Adds:)
$scope.$watch(
function () {
console.log(i);
return $scope.dependsOn[i];
},
function (newVal) {
if (newVal !== undefined) {
console.log("doesn't work");
}
}
);
You can fix this and the issue of variable hoisting by using a self calling closure to capture the value at the time of iteration and maintain that for your delegate.
http://jsfiddle.net/df6L0v8f/4/
for (var i = 0; i < $scope.dependsOn.length; i++) {
var watchDelegate = (function(itemDelegate){
return function () {
return itemDelegate;
};
})($scope.dependsOn[i]);
$scope.$watch(
watchDelegate,
function (newVal) {
if (newVal !== undefined) {
console.log(newVal());
}
}
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With