Reputation: 900
I have defined an items object inside the main app controller which has 3 Boolean items. I am sending this object to a directive which has isolated scope. In this directive, I am iterating over the received object with ng-repeat and creating check-boxes with ng-model = item in items object.
But I am not able to watch the changes on items object (done by ng-model on the directive). The $watchCollection which I have put doesn't seem to work.
JavaScript:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.items = {
item1: true,
item2: false,
item3: true
};
$scope.$watchCollection('items', function(newVal, oldVal) {
console.log(oldVal, newVal);
});
});
myApp.directive('testDirective', function() {
return {
restrict: 'E',
replace: true,
scope: {
items: '='
},
template: "<div ng-repeat='(item,val) in items'><label><input type='checkbox' ng-model='val'/>{{item}}</label></div>"
}
});
HTML:
<div ng-controller="MyCtrl">
<test-directive items="items"></test-directive>
</div>
However, if inside the directive HTML, I don't use ng-repeat and create individual check-boxes manually, then $watchCollection correctly watches the changes:
<div>
<label>
<input type='checkbox' ng-model='items.item1' />Item1</label>
<label>
<input type='checkbox' ng-model='items.item2' />Item2</label>
<label>
<input type='checkbox' ng-model='items.item3' />Item3</label>
</div>
Below is the JSFiddle link of the problem: https://jsfiddle.net/rishabh1990/0kb6tezd/
Upvotes: 1
Views: 1363
Reputation: 68665
$watchCollection will work only if your collection's data changes ( added, removed), not if the inner data changes.
For watching the inner data changes, you msut write
$scope.$watch('items', function(newVal, oldVal) {
console.log(oldVal, newVal);
}, true);
EDITED See here
https://jsfiddle.net/5bf3v0xj/
Why
$scope.items = [
{name: 'item1', value: true},
{name: 'item2', value: false},
{name: 'item3', value: true}
];
and not a
$scope.items = {
item1: true},
item2: false},
item3: true}
}
EXPLANATION
Because ng-repeat
creates it's own scope
and copies the primitives values.
string behave as a primitive value, so ng-repeat
will have it's own copies of this variables.And because you are watching to the originals ` not copies, it will never fire.
And one more thing: it is a good style to have a .
in the ng-repeat's variable :
like
ng-model='item.value
in the code.
Upvotes: 1