Reputation: 34630
I have a selected array which will hold all the items that are selected. So when you change a checkbox the item gets added or removed from that array. Problem is that if something else changes the selected array the checkboxes don't update.
Storing the selected state on the item it self isn't an option since in my app the items array gets repopulated depending on the url. So the selected array is a global array holding all the items you have selected. To give it some context my app is a file browser and you can select files in different directories.
Plunker
http://plnkr.co/edit/h9t3caBzk7hyTYJysCay?p=preview
js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.selected = ['one'];
$scope.items = ['one', 'two', 'three'];
$scope.select = function (item, s) {
if (s) {
return $scope.selected.push(item);
}
$scope.selected.splice($scope.selected.indexOf(item.path), 1);
}
});
app.controller('ItemCtrl', function ($scope) {
$scope.s = $scope.selected.some(function (i){
return i === $scope.item;
})
})
Html
<body ng-controller="MainCtrl">
<button ng-click='selected.length = 0'>Clear selected</button>
<p ng-repeat='item in items' ng-controller='ItemCtrl'>
<input type='checkbox' ng-change='select(item, s)' ng-model='s' /> {{item}}
</p>
{{selected}}
</body>
Upvotes: 0
Views: 725
Reputation: 583
I forked and modified your plunker a bit:
http://plnkr.co/edit/usoaJN8O0BE0J1vIdSwB?p=preview
So what I did was changed $scope.selected
into an object, and bound each checkbox's ng-model
to it, with the value of each item serving as the key (ng-model=selected[item]
).
I also added a function that will iterate through the $scope.selected
and return all the selected items in array format to match what I am assuming is your desired final output.
The reasoning I had for this approach is in general, I like to let ng-model
do all the work of managing whatever information I need (in this case what is selected or not) as well as the 2-way data binding. I feel like this usually yields less code as well as cleaner code.
Upvotes: 1
Reputation: 34630
One option is to wrap '$scope.s' assignment inside a '$scope.$watch'. It works but I wonder if there are better solutions.
$scope.$watch('selected.length', function () {
$scope.s = $scope.selected.some(function (i){
return i === $scope.item;
});
});
Upvotes: 0