深入理解angularjs $watch ,$apply 和 $digest --- 理解数据绑定过程
转自:http://www.angularjs.cn/A0a6
Angular用户都想知道数据绑定是怎么实现的。你可能会看到各种各样的词汇:$watch
,$apply
,$digest
,dirty-checking
... 它们是什么?它们是如何工作的呢?让我们从头开始吧。
浏览器事件循环和Angular.js扩展
我们的浏览器一直在等待事件,比如用户交互。假如你点击一个按钮或者在输入框里输入东西,事件的回调函数就会在javascript解释器里执行,然后你就可以做任何DOM操作,等回调函数执行完毕时,浏览器就会相应地对DOM做出变化。 Angular拓展了这个事件循环,生成一个有时成为angular context
的执行环境(记住,这是个重要的概念),为了解释什么是context
以及它如何工作,我们还需要解释更多的概念。
$watch 队列($watch list)
每次你绑定一些东西到你的UI上时你就会往$watch队列里插入一条$watch
。想象一下$watch
就是那个可以检测它监视的model里时候有变化的东西。例如你有如下的代码
index.html
User: <input type="text" ng-model="user" />
Password: <input type="password" ng-model="pass" />
在这里我们有个$scope.user
,他被绑定在了第一个输入框上,还有个$scope.pass
,它被绑定在了第二个输入框上,然后我们在$watch list
里面加入两个$watch
:
controllers.js
app.controller('MainCtrl', function($scope) {
$scope.foo = "Foo";
$scope.world = "World";
});
index.html
Hello, {{ World }}
这里,即便我们在$scope
上添加了两个东西,但是只有一个绑定在了UI上,因此在这里只生成了一个$watch
. 再看下面的例子:
index.html
<ul>
<li ng-repeat="person in people">
{{person.name}} - {{person.age}}
</li>
</ul>
这里又生成了多少个$watch
呢?每个person有两个(一个name,一个age),然后ng-repeat又有一个,因此10个person一共是(2 * 10) +1
,也就是说有21个$watch
。 因此,每一个绑定到了UI上的数据都会生成一个$watch
。对,那这写$watch
是什么时候生成的呢? 当我们的模版加载完毕时,也就是在linking阶段(Angular分为compile阶段和linking阶段---译者注),Angular解释器会寻找每个directive,然后生成每个需要的$watch
。听起来不错哈,但是,然后呢?
$digest
循环(这个digest不知道怎么翻译)
还记得我前面提到的扩展的事件循环吗?当浏览器接收到可以被angular context
处理的事件时,$digest
循环就会触发。这个循环是由两个更小的循环组合起来的。一个处理evalAsync
队列,另一个处理$watch
队列,这个也是本篇博文的主题。 这个是处理什么的呢?$digest
将会遍历我们的$watch
,然后询问:
- 嘿,
$watch
,你的值是什么?- 是9。
- 好的,它改变过吗?
- 没有,先生。
- (这个变量没变过,那下一个)
- 你呢,你的值是多少?
- 报告,是
Foo
。
- 报告,是
- 刚才改变过没?
- 改变过,刚才是
Bar
。
- 改变过,刚才是
- (很好,我们有DOM需要更新了)
- 继续询问知道
$watch
队列都检查过。
这就是所谓的dirty-checking
。
例如: controllers.js
app.controller('MainCtrl', function() {
$scope.name = "Foo";
$scope.changeFoo = function() {
$scope.name = "Bar";
}
});
index.html
{{ name }}
<button ng-click="changeFoo()">Change the name</button>
这里我们有一个$watch
因为ng-click不生成$watch
(函数是不会变的)。
- 我们按下按钮
- 浏览器接收到一个事件,进入
angular context
(后面会解释为什么)。 $digest
循环开始执行,查询每个$watch
是否变化。- 由于监视
$scope.name
的$watch
报告了变化,它会强制再执行一次$digest
循环。 - 新的
$digest
循环没有检测到变化。 - 浏览器拿回控制权,更新与
$scope.name
新值相应部分的DOM。
这里很重要的(也是许多人的很蛋疼的地方)是每一个进入angular context
的事件都会执行一个$digest
循环,也就是说每次我们输入一个字母循环都会检查整个页面的所有$watch
。
通过$apply
来进入angular context
谁决定什么事件进入angular context
,而哪些又不进入呢?$apply
!
如果当事件触发时,你调用$apply
,它会进入angular context
,如果没有调用就不会进入。现在你可能会问:刚才的例子里我也没有调用$apply
啊,为什么?Angular为了做了!因此你点击带有ng-click的元素时,时间就会被封装到一个$apply
调用。如果你有一个ng-model="foo"
的输入框,然后你敲一个f
,事件就会这样调用$apply("foo = 'f';")
。
后文见下一篇文章!
深入理解angularjs $watch ,$apply 和 $digest --- 理解数据绑定过程的更多相关文章
- 理解$watch ,$apply 和 $digest --- 理解数据绑定过程
原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...
- 深入理解$watch ,$apply 和 $digest --- 理解数据绑定过程——续
Angular什么时候不会自动为我们$apply呢? 这是Angular新手共同的痛处.为什么我的jQuery不会更新我绑定的东西呢?因为jQuery没有调用$apply,事件没有进入angular ...
- [转]理解$watch ,$apply 和 $digest --- 理解数据绑定过程
原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...
- 理解$watch、$apply与$digest
Angular环境 浏览器里面有一个事件队列(event queue),用户触发啥事儿,或者网络请求,延时操作(例如定时器之类),都是一个event,浏览器会轮询这些事件,然后调用这些回调(这里的回调 ...
- 理解Angular中的$apply()以及$digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- 深入理解Angular中的$Apply()以及$Digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- 通俗理解angularjs中的$apply,$digest,$watch
<!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...
- (网页)理解Angular中的$apply()以及$digest()
转自CSDN: 工作有问题上CSDN上转转. $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$ ...
- (转) 理解Angular中的$apply()以及$digest()
原文地址:http://blog.csdn.net/dm_vincent/article/details/38705099 $apply()和$digest()在AngularJS中是两个核心概念,但 ...
随机推荐
- gcc与glibc关系
glibc是什么,以及与gcc的关系? glibc是gnu发布的libc库,也即c运行库.glibc是linux 系统中最底层的api(应用程序开发接口),几乎其它任何的运行库都会倚赖于glibc.g ...
- 20145302张薇 《网络对抗》MSF应用基础
20145302张薇 <网络对抗>MSF应用基础 实验内容 掌握metasploit的基本应用方式 1.主动攻击--ms08_067 2.针对浏览器的攻击--ms11_050 3.针对客户 ...
- 20145329 《网络对抗技术》浏览器MS11_050安全漏洞攻击
两台虚拟机: kali ip:192.168.96.130 windows xp sp3(包含IE7)ip:192.168.96.128 1.在kali终端中开启msfconsole. 2.进入漏洞模 ...
- 20165211 获奖感想及java课程总结
20165211 获奖感想及java课程总结 理论脱离实践是最大的不幸.--达芬奇 这句话,是我在学习Java之前,假期内写的20165211 学习基础和C语言调查里的所引用的一句话,是当时我对Jav ...
- 字符串分割(C++)(转载)
转载出自:http://www.cnblogs.com/MikeZhang/archive/2012/03/24/MySplitFunCPP.html 经常碰到字符串分割的问题,这里总结下,也方便我以 ...
- python面向对象总结!
面向对象 Object Oriented Programming 基本单元:对象把数据和功能封装在里边,能实现很好的复用性,灵活性和扩展性. 面向对象的两个基本概念:类和对象 面向对象的基本要素:属性 ...
- Python3基础 getattr 获取对象的指定属性值
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- Window下Latex加速编译方法以及西农毕设论文模板推荐
近些日子用Latex写了一遍文章,一共有11页,但是在window下编译需要2分多的时间,使用的是xeletex编译器. 经过查找,得到了以下方法: 如果坚持使用windows下的latex,使用以下 ...
- HDU 6143 Killer Names(容斥原理)
http://acm.hdu.edu.cn/showproblem.php?pid=6143 题意: 用m个字母去取名字,名字分为前后两部分,各由n个字符组成,前后两部分不能出现相同字符,问合法的组成 ...
- UVa 1152 和为0的4个值(二分查找)
https://vjudge.net/problem/UVA-1152 题意:给定4个n元素集合A,B,C,D,要求分别从中选取一个元素a,b,c,d,使得a+b+c+d=0.问有多少种取法. 思路: ...