Let's say I have to store customer information, and to manage two-way binding I'll use $scope
here.
So my doubt here is, which approach is better?
$scope.firstname = "foo";
$scope.lastname = "bar";
$scope.cellno = "1234567890";
$scope.email = "[email protected]";
OR
$scope.customerDetailsObj = {};
$scope.customerDetailsObj.firstname = "foo";
$scope.customerDetailsObj.lastname = "bar";
$scope.customerDetailsObj.cellno = "1234567890";
$scope.customerDetailsObj.email = "[email protected]";`
I've been wondering about this because I have a large angular application and sometimes the scope watchers count goes beyond 1500. I'm using a chrome extension to see watchers count.
Please share your views. Thank You.
AngularJS Scope The scope is the binding part between the HTML (view) and the JavaScript (controller). The scope is an object with the available properties and methods. The scope is available for both the view and the controller.
Scope hierarchyEach Angular application has a root scope and can have any number of child scopes. The root scope is created whenever the Angular application is created, but then, directives cam create new child scopes. When a new child scope is created it is added as a child of his parent scope.
The $ in "$scope" indicates that the scope value is being injected into the current context. $scope is a service provided by $scopeProvider . You can inject it into controllers, directives or other services using Angular's built-in dependency injector: module.
In my opinion and as-per angularjs guide first approach (binding to properties directly) will be more efficient. Excerpt from the guide:
Dirty checking can be done with three strategies: By reference, by collection contents, and by value. The strategies differ in the kinds of changes they detect, and in their performance characteristics.
- Watching by reference (scope.$watch (watchExpression, listener)) detects a change when the whole value returned by the watch expression switches to a new value. If the value is an array or an object, changes inside it are not detected. This is the most efficient strategy.
- Watching collection contents (scope.$watchCollection (watchExpression, listener)) detects changes that occur inside an array or an object: When items are added, removed, or reordered. The detection is shallow - it does not reach into nested collections. Watching collection contents is more expensive than watching by reference, because copies of the collection contents need to be maintained. However, the strategy attempts to minimize the amount of copying required.
- Watching by value (scope.$watch (watchExpression, listener, true)) detects any change in an arbitrarily nested data structure. It is the most powerful change detection strategy, but also the most expensive. A full traversal of the nested data structure is needed on each digest, and a full copy of it needs to be held in memory.
Talking only about performance, I think option 1 (having plain variables) it's more efficient.
Watching plain properties
the $watch() function, by default only checks object reference equality. So within each $digest it will check to see if the new and old values pointing to the same object.
Watching objects and arrays
If you want to $watch() an object, you have to switch to the deep watch and that means that within each $digest, it will check the whole tree to see if the structure or values are changed. So, bigger the object, more expensive the check.
$watchGroup(), an alternative to objects/array watchers
If you have a group of related properties like ie a person (name, surname, age), you could define it like plain properties, and use $watchGroup(), that works on the same way like a common $watch() but taking a list of properties to watch rather than one.
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