Reputation: 1251
This question is based in this previous one
I have a ng-repeat
like this:
<li ng-repeat="opt in namesCtrl.uniqueCars">
<input type="checkbox" ng-model="namesCtrl.filter['cars'][opt.element]" | orderBy:['checkbox','-count']"><p2>{{opt.element}} ({{opt.count}})</p2>
</li>
Where the elements are taken from this.uniqueCars
this.uniqueCars=[
{'element':'Ford','count':3,'checkbox':false},
{'element':'Honda','count':2,'checkbox':false},
{'element':'Ferrari','count':1,'checkbox':false},
{'element':'Delorean','count':6,'checkbox':false}
];
And the checked items in the view go to this.filter
(that I use for another purpose)
this.filter = {
"cars": {}
}
So what I want to achieve is to order the checkbox list in the view, so when one of the items is checked, it would go to the top, something like this
In order to do that, I have a $watch
that goes like this
$scope.$watch("namesCtrl.filter", function(nv,ov){
angular.forEach(self.uniqueCars, function(opt){
opt.checkbox = nv.cars[opt.element]
})
}, true)
But the behavior is pretty inconsistent when ordering by the checkbox value (when first clicking it does the job, OK, but when unclicking it doesn't work, and when clicking again it sorts it in the opposite way).
So I would like to do this by modifying the $watch
. (I do it this way as IRL this.filter
could be modified by other elements, so I need to watch the changes there).
PS: the this.uniqueCars.checkbox
the field is inserted by me just in order to make the sorting possible, so it would be safe to modify it.
You can check the working Plunker here.
Upvotes: 1
Views: 572
Reputation: 2462
Why can't you modify checkbox
propery itself? Changing input's model to opt.checkbox
and commenting watch out make everything work. I think it's better this way.
But you can modify opt.checkbox = nv.cars[opt.element]
to opt.checkbox = !!nv.cars[opt.element]
to make it work too (the checkbox property in cars
object is undefined
, that breaks proper ordering).
Upvotes: 1
Reputation: 5357
You almost got it right.
There was a small problem with your $watch
function: In the case where a car is not yet a member of namesCtrl.filter
, its checkbox
value is removed from namesCtrl.uniqueCars
because it's undefined.
If you handle this case like this:
$scope.$watch("namesCtrl.filter", function(nv,ov){
angular.forEach(self.uniqueCars, function(opt){
var value = nv.cars[opt.element] ? nv.cars[opt.element].checkbox : false;
opt.checkbox = value;
});
}, true);
Then your ordering is fine. Except you also need to order by checkbox in reverse order:
<li ng-repeat="opt in namesCtrl.uniqueCars | orderBy:['-checkbox','-count']">
See working plunker.
Upvotes: 2