For watching an object scope variable, is $scope.$watch
with objectEquality
set to true OR $scope.$watchCollection
better?
For a $scope
object variable (like 15 attributes, some nested 2 levels deep) updated with input elements and ng-model
in the view, how bad is $scope.$watch
with objectEquality
set to true
? Is this a big thing to avoid?
Is $watchCollection
a better solution?
I am looking for easy wins to improve performance on my AngularJS App (I'm still stuck on v1.2.2).
// ctrl scope var $scope.filters = { name: '', info: {test: '', foo: '', bar: ''}, yep: '' // etc ... } // ctrl watch ? $scope.$watch('filters', function(newVal, oldVal) { if(newVal !== oldVal) { // call with updated filters } }, true); // or ctrl watch collection ? $scope.$watchCollection('filters', function(newVal, oldVal) { if(newVal !== oldVal) { // call with updated filters } }); // view input with ng-model <input type="text" ng-model="filters.name" /> <input type="text" ng-model="filters.info.test" /> <input type="text" ng-model="filters.yep" /> // etc ...
$watch() function is used to watch the changes of variables in $scope object. Generally the $watch() function will create internally in Angularjs to handle variable changes in application.
$watch() is used to watch changes, for example in some input fields. This function always returns old value and new value. $watchCollection() is used when trying to push something to a collection, or when removing some elements from it. This function returns previous collection and new collection.
$watch() will be triggered by:
$scope.myArray = []; $scope.myArray = null; $scope.myArray = someOtherArray;
$watchCollection() will be triggered by everything above AND:
$scope.myArray.push({}); // add element $scope.myArray.splice(0, 1); // remove element $scope.myArray[0] = {}; // assign index to different value
$watch(..., true) will be triggered by EVERYTHING above AND:
$scope.myArray[0].someProperty = "someValue";
JUST ONE MORE THING...
$watch() is the only one that fires when an array is replaced with another with the same exact content. For example:
$scope.myArray = ["Apples", "Bananas", "Orange" ]; var newArray = []; newArray.push("Apples"); newArray.push("Bananas"); newArray.push("Orange"); $scope.myArray = newArray;
Below is a link to an example JSFiddle that uses all the different watch combinations and outputs log messages to indicate which "watches" were triggered:
http://jsfiddle.net/luisperezphd/2zj9k872/
The
$watchCollection()
function is a sort-of mid-ground between the two$watch()
configurations above. It's more in-depth than the vanilla $watch() function; but, it's not nearly as expensive as the deep-equality$watch()
function. Like the$watch()
function, the$watchCollection()
works by comparing physical object references; however, unlike the$watch()
function, the$watchCollection()
goes one-level deep and performs an additional, shallow reference check of the top level items in the collection.
see this explanation
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With