How can I view a property for changes in a filtered array of objects when I filter that same property?
How to do it:
$scope.$watch('item.completed', function(to, from){ …
combined with this:
<li ng-repeat="item in items | filter:{completed: true}" ng-controller="ItemCtrl"> …
Live plunker example: http://plnkr.co/edit/pdFkEmxyqrzS6mc2AYo2?p=preview
At the present time, when I change the property of the item
object completed
, $watch()
does not start.
I suspect it has something to do with referencing the property of the filter properties, but how do I do it otherwise? I've also tried $watch(…, …, true)
and $watchCollection()
but has no effect.
source to share
You can listen for the scope destroy event and get the value from the event object:
.controller('ItemCtrl', ['$scope', function($scope){
$scope.$on('$destroy', function(o){log(o.targetScope.item.name + '(' + o.targetScope.item.completed + '):destroyed')});
$scope.$watch('item.completed', function(to, from){
log(from + ' --> ' + to);
});
}]);
source to share
I'm still not entirely sure I understand the end goal. I think you are saying that you want to be able to register when an item changes in the filtered list. I can think of a couple of imperfect approaches.
- Forget about the watch completely. Just call the function on
ng-change
to enter the checkbox: http://plnkr.co/edit/IeAt4a31So7zjMJzptIp?p=preview - Create a deep scan of an array of elements through
$scope.$watch('items', listener, true)
. The third argumenttrue
will cause the object check to be used , after which you can compare after the array and log states that changed each time: http://plnkr.co/edit/gg5DPWJhx8syhNhelFOT?p=preview
Not only exactly watch
which gives you a certain changed item in the list, but I think you can get what you eventually need to do via these routes.
source to share
This is a hacky way to do it, but I think it does what the OP wants:
http://plnkr.co/edit/wGRJIGJbALjMQqeffCyF?p=preview
It also proves that jonasnas and PSL were absolutely right.
The idea is to do it in controllers:
.controller('ItemsCtrl', ['$scope', function($scope){
$scope.items = [
{name: 'item 1', completed: true},
{name: 'item 2', completed: true},
{name: 'item 3', completed: true},
{name: 'item 4', completed: false},
{name: 'item 5'},
{name: 'item 6', completed: true},
];
$scope.itemsToWatch=[];
$scope.watchMe = function(item){
var myIdx = $scope.items.indexOf(item);
if($scope.itemsToWatch.indexOf(myIdx)==-1){
$scope.itemsToWatch.push(myIdx);
$scope.$watch('items[' + myIdx + '].completed', function(to, from){
log(from + ' --> ' + to);
});
}
};
}])
.controller('ItemCtrl', ['$scope',function($scope){
$scope.$parent.watchMe($scope.item);
}]);
I don't think there would ever be anything like this in the code, but it was interesting to find a way to resolve the issue, and I learned a few things along the way.
source to share