Reputation: 4834
I have an AngularJs component having bindings to heroes, which is an array. How to watch this input for array changes? I tried $scope.watch("heroes", ...)
and $onChanges
, but didn't work so far.
bindings: {
heroes: '<',
}
Here is my plunker: https://plnkr.co/edit/J8xeqEQftGq3ULazk8mS?p=preview
Upvotes: 2
Views: 2378
Reputation: 4834
The ControllerAs structure needs a special watch expression, since the attributes are not on the $scope.
//This one works and is the best one (> AngularJs 1.5)
$scope.$watch("$ctrl.heroes.length", function () {
console.log("ControllerAs syntax"); // Triggers once on init
});
//This one works as well
var ctrl = this;
$scope.$watch(() => {
return ctrl.heroes.length;
}, (value) => {
console.log("complex watch"); // Triggers once on init
});
See example here: https://plnkr.co/edit/J8xeqEQftGq3ULazk8mS?p=preview
Upvotes: 4
Reputation: 10703
The issue occurs because $scope.$watch by default doesn't deeply watch objects. Which means since you never destroy/recreate your array, the reference doesnt really change therefore $scope.$watch
doesnt see any change. If you watched heroes.length
, that primitive would change and your $scope.$watch
would fire the corresponding listening function. By using $scope.$watch
with the true
option you are telling the angular engine to deeply watch all properties.
This is pretty intensive to do for large objects because $scope.$watch
using angular.copy
to track changes
If you were to use $scope.$watchCollection
angular would create a shallow copy and would be less memory intensive. So I feel your 3 main options are
Watch heroes.length
, add true
or use $watchCollection
I feel that using heroes.length
would be your best bet, so the code would look like
$scope.$watch('heroes.length',function(){});
The other two options are described below
$scope.$watch('heroes',function(){
//do somthing
},true)
or
$scope.$watchCollection
The benefit of using watchCollection is, that it requires less memory to deeply watch an object.
Shallow watches the properties of an object and fires whenever any of the properties change (for arrays, this implies watching the array items; for object maps, this implies watching the properties). If a change is detected, the listener callback is fired.
The obj collection is observed via standard $watch operation and is examined on every call to $digest() to see if any items have been added, removed, or moved. The listener is called whenever anything within the obj has changed. Examples include adding, removing, and moving items belonging to an object or array.
Upvotes: 0