This article mainly introduces the application of $watch, $apply and $digest of AngularJS two-way data binding principle. It has certain reference value. Interested friends can refer to it
Introduction
This article is written for AngularJS newbies. If you already have an in-depth understanding of AngularJS’s two-way data binding, just go and read the source code.
Background
AngularJS developers all want to know how two-way data binding is implemented. There are many terms related to data-binding: $watch, $apply, $digest, dirty-checking, etc. How do they work? Let’s start from the beginning
The two-way data binding of AngularJS is forced by the browser
The browser looks beautiful, but in fact, in the aspect of data interaction Son, due to the browser's "inaction", the browser's data refresh has become a problem. Specifically, the browser can easily listen to an event, such as when the user clicks a button or enters something in the input box. It also provides an API for event callback functions. The event callback function will be executed in the javascript interpreter. but the reverse is not so simple. If the data from the background changes, the browser needs to be notified and refreshed. The browser does not provide such a data interaction mechanism. For developers, this It is an insurmountable obstacle, what should I do? AngularJS appears, which implements two-way data binding well through $scope. The principle behind it is $watch, $apply, $digest, dirty-checking
$watch queue ($watch list)
Literally, watch means to observe. Every time you bind something to the browser, a $watch will be inserted into the $watch queue. Imagine that $watch is something that can detect changes in the model it monitors. For example, you have the following code
User: <input type="text" ng-model="user" /> Password: <input type="password" ng-model="pass" />
There is $scope.user, which is bound to the first input box, and there is $scope.pass, which is bound to the second input box. on an input box; then add two $watches to the $watch list:
Create a controllers.js file with the following code:
app.controller('MainCtrl', function($scope) { $scope.foo = "Foo"; $scope.world = "World"; });
The corresponding html file, the index.html code is as follows :
Hello, {{ World }}
Here, even if two things are added to $scope, only one is bound to the UI, so only one $watch is generated. Look at the following example:
controllers.js
app.controller('MainCtrl', function($scope) { $scope.people = [...]; });
The corresponding html file index.html
<ul> <li ng-repeat="person in people"> {{person.name}} - {{person.age}} </li> </ul>
It seems that multiple $watches are generated. Each person has two (one name, one age), and ng-repeat is a loop, so the total of 10 persons is (2 * 10) 1, which means there are 21 $watches. Therefore, every data bound to the browser will generate a $watch. Yes, when was $watch generated? Let’s first review the loading principle of AngularJS
The loading principle of AngularJS:
The template loading of AngularJS is divided into two stages: compilation and linking. During the linking phase, the AngularJS interpreter will look for each directive and generate each required $watch. By the way, $watch is generated at this stage.
Next, let’s start using $digest
$digest loop
Literally, digest means “digestion”. I feel that this name is weird. It is strangely related to dirty-checking, which literally means "dirty checking". It is better not to translate it. The original author's original intention is definitely not this, it can only be understood but not expressed in words!
$digest is a loop, what is it doing in the loop? $digest is iterating over our $watch. $digest asks $watch one by one - "Hey, has the data you observed changed?"
This traversal is the so-called dirty-checking. Now that all $watches have been checked, we have to ask: Has $watch been updated? If at least one has been updated, the loop will be triggered again until all $watches are unchanged. This ensures that each model will not change again. Remember that if the loop exceeds 10 times, it will throw an exception to avoid an infinite loop. When the $digest loop ends, the DOM changes accordingly.
Look at the code, for example: controllers.js
app.controller('MainCtrl', function() { $scope.name = "Foo"; $scope.changeFoo = function() { $scope.name = "Bar"; } });
The corresponding html file, index.html
{{ name }} <button ng-click="changeFoo()">Change the name</button>
There is only one $watch here, because ng-click does not generate $ watch (the function will not change).
$digest execution process is:
Press the button in the browser;
The browser receives an event , enter the angular context.
The $digest loop begins to execute, querying whether each $watch changes.
Because the $watch monitoring $scope.name reports a change, it will force another $digest cycle.
The new $digest loop does not detect changes. At this time, the browser takes back control and updates the DOM corresponding to the new value of $scope.name.
We can see an obvious shortcoming of AngularJS: every event entering the angular context will execute a $digest loop. Even if you only enter a letter, $digest will traverse the entire page. of all $watch.
$apply’s application
Angular context 是整个Angular的上下文,也可以把它理解为Angular容器,那么,是谁来决定哪些事件可以进入 Angular Context,哪些事件又不能进入呢? 其控制器在 $apply手上。
如果当事件触发时,调用$apply,它会进入angular context,如果没有调用就不会进入。你可能会问:刚才的例子并没有调用$apply,这是怎么回事呢?原来,是Angular背后替你做了。当点击带有ng-click的元素时,事件就会被封装到一个$apply调用中。如果有一个ng-model="foo"的输入框,当输入一个字母 f 时,事件就会这样调用,$apply("foo = 'f';")。
$apply的应用场景
$apply是$scope的一个函数,调用它会强制一次$digest循环。如果当前正在执行$apply循环,则会抛出一个异常。
如果浏览器上数据没有及时刷新,可以通过调用$scope.$apply() 方法,强行刷新一遍。
通过 $watch 监控自己的$scope
<!DOCTYPE html> <html ng-app="demoApp"> <head> <title>test</title> <!-- Vendor libraries --> <script src="lib/jquery-v1.11.1.js"></script> <script src="lib/angular-v1.2.22.js"></script> <script src="lib/angular-route-v1.2.22.js"></script> </head> <body> <p ng-controller="MainCtrl" > <input ng-model="name" /> Name updated: {{updated}} times. </p> <script > var demoApp = angular.module('demoApp',[]); demoApp.controller('MainCtrl', function($scope) { $scope.name = "Angular"; $scope.updated = -1; $scope.$watch('name', function() { $scope.updated++; }); }); </script> </body> </html>
代码说明:
当controller 执行到 $watch时,它会立即调用一次,所以把updated的值设为 -1 。 上输入框中输入字符发生变化时,你会看到 updated 的值随之变化,而且能显示变化的次数。
$watch 检测到的数据变化
小结
我们对 AngularJS的双向数据绑定有了一个初步的认识,对于AngularJS来说,表面上看操作DOM很简单,其实背后有 $watch、$digest 、 $apply 三者在默默地起着作用。这个遍历检查数据是否发生变化的过程,称之为:dirty-checking。 当你了解了这个过程后,你会对它嗤之以鼻,感觉这种方法好low 哦。 确实,如果一个DOM中有 2000- 3000个 watch,页面的渲染速度将会大打折扣。
这个渲染的性能问题怎么解决呢?随着ECMAScript6的到来,Angular 2 通过Object.observe 极大地改善$digest循环的速度。或许,这就是为什么 Angular 团队迫不及待地推出 Angular 2 的原因吧。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of AngularJS two-way data binding principle (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!

JavaScript core data types are consistent in browsers and Node.js, but are handled differently from the extra types. 1) The global object is window in the browser and global in Node.js. 2) Node.js' unique Buffer object, used to process binary data. 3) There are also differences in performance and time processing, and the code needs to be adjusted according to the environment.

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

WebStorm Mac version
Useful JavaScript development tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Atom editor mac version download
The most popular open source editor

Dreamweaver CS6
Visual web development tools
