Why is Angular reading $ scope more than necessary?

I noticed that Angular is less than conservative when it comes to reading $ scope properties. When the application / controller first creates an instance, each binding property defined in the model opened through $ scope is read twice. When a property changes, all related properties are read again.

Can someone explain why (or am I doing something wrong)?

Here is some code to illustrate.

I have defined two properties of the object so that I can console.log at any time to read the property.

Obj object

 var obj = []; Object.defineProperty(obj, "a", { get: function(){ console.log("get obj.a: " + this.aVal); return this.aVal; }, set: function(val){ this.aVal = val; console.log("set obj.a = " + this.aVal); } }); Object.defineProperty(obj, "b", { get: function(){ console.log("get obj.b: " + this.bVal); return this.bVal; }, set: function(val){ this.bVal = val; console.log("set obj.b = " + this.bVal); } }); 

Angular app:

 var app = angular.module("App", []) .controller("TestCtrl", function($scope){ $scope.foo = obj; }); 

and HTML:

 <div ng-app="App"> <div ng-controller="TestCtrl"> <input type="text" ng-model="foo.a"></input> <input type="text" ng-model="foo.b"></input> </div> </div> 

Result

The console log is as follows:

the first time the application is launched, both properties are called twice:

 get obj.a: undefined get obj.b: undefined get obj.a: undefined get obj.b: undefined 

when you enter "x" for obj.a, both properties are read again

 set obj.a = x get obj.a: x get obj.b: undefined 
0
source share
2 answers

Angular handles two-way binding. How this happens is a dirty test. It checks for any observable property at the top of the digest, and then at the bottom of the digest (twice). He then compares the values ​​to see if something has changed. That is how he knows if he needs to reinstall the user interface. Read this article for reference.

A digest loop is executed anytime a call to $apply is visible in an area. Angular does this often (inside its own directives, like ng-click ).

+1
source

Try to catch the firebug stack, but it seems (as I know angular) that it is from a $ watch implementation - it must first evaluate the current hash of the object in order to begin to "listen" to its changes. Thus, the first reading of an object is an internal check, and the second is for viewing. Not sure, but he has to read objects twice to implement the magic of $ watch.

0
source

Source: https://habr.com/ru/post/977551/


All Articles