AngularJS的数据双向绑定是怎么实现的?

关于 AngularJS 的数据绑定

单向绑定(ng-bind) 和 双向绑定(ng-model) 的区别:
ng-bind 单向数据绑定($scope -> view),用于数据显示,简写形式是 {{}}
<span ng-bind="val"></span>
两者的区别在于页面没有加载完毕 {{val}}会直接显示到页面,直到 Angular 渲染该绑定数据(这种行为有可能将 {{val}}让用户看到);而 ng-bind则是在 Angular 渲染完毕后将数据显示。ng-model是双向数据绑定($scope -> view and view ->$scope),用于绑定值会变化的表单元素等。<input type="text" ng-model="val" />

之前的总结:  2.4.0 angular双向数据绑定

有三个概念:

  • $digest():脏值检查循环
  • $watch:添加监听
  • $apply:提供上下文执行表达式

双向数据绑定(bi-directional)意味着如果视图改变了某个值,数据模型会通过脏检查观察到这个变化,而如果数据模型改变了某个值,视图也会依据变化重新渲染。

当你写下表达式如{{ aModel }}时,AngularJS在幕后会为你在scope模型上设置一个watcher,它用来在数据发生变化的时候更新view。这里的watcher和你会在AngularJS中设置的watcher是一样的

对于所有绑定给同一$scope元素的UI对象,只会添加一个$watch到$watch列表中(一个数据一个$watcher,对象会有一个,里面的值还会有,数组中每个对象都有一个 )。这些$watch列表会在$digest循环中通过一个叫做“脏值检查”的程序解析

  • 假设你在一个ng-click指令对应的handler函数中更改了scope中的一条数据
  • 此时AngularJS会自动地通过调用$digest()来触发一轮$digest循环。
  • 当$digest循环开始后,它会触发每个watcher。
  • 这些watchers会检查scope中的当前model值是否和上一次计算得到的model值不同。
  • 如果不同,那么对应的回调函数会被执行。调用该函数的结果,就是view中的表达式内容(译注:诸如{{ aModel }})会被更新。

除了ng-click指令,还有一些其它的built-in指令以及服务来让你更改models(比如ng-model,$timeout等)和自动触发一次$digest循环。如下:

谈起angular的脏检查机制(dirty-checking), 常见的误解就是认为: ng是定时轮询去检查model是否变更。 其实,ng只有在指定事件触发后,才进入$digest cycle:

  • DOM事件,譬如用户输入文本,点击按钮等。(ng-click)
  • XHR响应事件 ($http)
  • 浏览器Location变更事件 ($location)
  • Timer事件($timeout, $interval)
  • 执行$digest()或$apply()
    上述事件发生->$digest()循环->触发每个watcher->watcher检查scope中的当前model值和上一次计算得到的model值是否不同->如果不同,那么$watch()对应的回调函数会被执行->调用该函数的结果,就是view中的表达式内容(译注:诸如{{ aModel }})会被更新

angularJS并不直接调用$digest(),而是调用$scope.$apply(),后者会调用$rootScope.$digest()。因此,一轮$digest循环在$rootScope开始,随后会访问到所有的children scope中的watchers

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值