angular中的双向数据绑定

angularjs使用者想要知道数据绑定(data-binding)是如何工作的,就会遇到很多的关的术语,比如$wacth,$apply,$digest,dirty-checking(脏值检测)...等等,这些又是做什么的呢?

先介绍一下重要背景~三个概念~

  • Dirty Checking – AngularJS内部比较value现在的值和之前的值,如果发生了改变,就触发change事件。
  • Digest – 执行Dirty Checking的机制,由$digest()触发。
  • Apply – 当dom事件在AngularJS机制外被触发时,需要通知AngularJS进行Digest。由$apply触发。

1.每当你在ui上绑定了东西(比如使用ng-model,  {{name}}),就会添加了一个$wacth到$watch list中,你可以把$watch想象成为一个能够察觉model的变化的检测器;当我们在ui上使用(绑定)用directives 指令的时候,就创建了一个$watch,那它是什么时候创建的呢? 当我们的模板加载完成(亦叫做linking phase),compiler就会找到所有的指令,并创建对应的$watch。

2.当浏览器发送一个事件,我们就能通过angular context管理这个事件,此时$digest就会被激活 ( 除了ng-click之外,还有其他一些内置的指令/服务可以让你更改模型(例如ng-model,$timeout 等),并自动触发一个 $digest循环。)

这个事件轮询loop由两个小loop组成,

一个是处理$evalAsync队列

一个是处理$watch list,这就是本文的主题了。

那处理的过程是怎样的?$digest会轮询我们有的$watch list 看数据是否改变,大概就像下面这样

---》Hey,$watch,你的value值是多少啊?

---》我的value值是9。

---》好的,有变化吗?

---》没有。

(什么都没有变化,就会跳到下个继续询问)

---》来,你的value值是多少啊?

---》是foo。

---》有变化吗?

---》有啊,本来是bar的

(很好,那么现在我们有一个DOM要更新下了)

流程就会这样继续下去,直到$watch list中所有的$watch都被询问...

$degest loop完成,DOM就会发生改变

 

现在讲下脏值检测(dirty-checking),现在所有的$watch都被轮询过了,

会再次询问是否所有的$watch都已经更新了?

如果其中有一个改变了,就会重新轮询,直到所有的$wacth没有改变。这样做事为了确保所有的model都是“干净的”

注意:如果轮询loop超过十次,就会抛出异常,来退出无限的轮询。

angular使用dirty(脏值)检查机制来实现了双向绑定,大体思路为:通过watch一遍又一遍地监听脏值也就是所说的脏值检查,当某个dirty由false变为true时,触发view重新渲染。

通过$digest的理解,我们知道是存在DOM事件,XHR响应事件,Location变更,定时器$timeout, $interval的情况下angular认为需要检查数据有无变化时才会调用$apply进而调用了$digest遍历监听。当一些变量被改变时并不在上述几种情况下,如使用原生的setTimeout()而非$timeout时,因为angular没有自动调用$apply所以我们需要手动调用以下$apply。

最后,我希望你看完就明白了 Angular中data-binding的工作原理,我猜你看完的第一印象会觉得dirty-checking是很慢的

实际上它是很快的,实际上只有页面上达到2000-3000 个$watch的时候,它才会出现性能上的延迟。一般的应用应该不会有这么复杂,否则就要思考一下是否设计不合理了。

引用:http://www.cnblogs.com/cunjieliu/p/4370441.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值