Reputation: 259
I am trying to do a simple angularJS test with a input[type=checkbox] and show the number of items that are selected. Currently, my solution looks like this:
$scope.items = [{
id: 1,
title: 'item1',
selected: true
},{
id: 2,
title: 'item2',
selected: false
},{
id: 3,
title: 'item3',
selected: false
},{
id: 4,
title: 'item4',
selected: false
}]
$scope.$watchCollection('items', function() {
var no = 0;
for(var i = 0; i < $scope.items.length; i++) {
if($scope.items[i].selected === true)
no++;
}
$scope.noSelectedItems = no;
}
<div>Items ({{ noSelectedItems }})</div>
<div ng-repeat="item in items">
<input id="{{ item.id }}"
type="checkbox"
ng-model="item.selected"
ng-checked="item.selected" />
<label for="{{ item.id }}" >{{ item.title }}</label>
</div>
The initialization works, so I get "Items (1)" but when I select more items, the $scope.items doesn't update at all.
Can anyone explain why?
Thank you.
Upvotes: 1
Views: 53
Reputation: 5100
You need to do a deep watch in your collection, using the third parameter (true) in $watch. See the working JSFiddle: http://jsfiddle.net/syv8cww1/
$scope.$watch('items', function() {
var no = 0;
for(var i = 0; i < $scope.items.length; i++) {
if($scope.items[i].selected === true)
no++;
}
$scope.noSelectedItems = no;
}, true);
Upvotes: 2
Reputation: 2983
$watchCollection
is not designed to watch updates inside objects in an array of objects. See offical docs for more infos.
You can resolve your problem by using ngChange
directive.
HTML :
<div ng-repeat="item in items">
<input id="{{ item.id }}"
type="checkbox"
ng-model="item.selected"
ng-checked="item.selected"
ng-change="doSomething()"/>
</div>
Controller :
$scope.doSomething = function() {
var no = 0;
for(var i = 0; i < $scope.items.length; i++) {
if($scope.items[i].selected === true) {
no++;
}
}
$scope.noSelectedItems = no;
}
Upvotes: 0