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!

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

Python is more suitable for data science and machine learning, while JavaScript is more suitable for front-end and full-stack development. 1. Python is known for its concise syntax and rich library ecosystem, and is suitable for data analysis and web development. 2. JavaScript is the core of front-end development. Node.js supports server-side programming and is suitable for full-stack development.


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

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

WebStorm Mac version
Useful JavaScript development tools