美文网首页全栈工程师angularjs
AngularJS的数据双向绑定是怎么实现的?

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

作者: darr250 | 来源:发表于2016-11-29 15:20 被阅读2304次

    👍: 关于 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

    相关文章

      网友评论

      • 沫璃宠儿:跳的太厉害。。没看懂
        darr250:@沫璃宠儿 恩恩,我自己总结的是有点乱。可以看看我参考的那篇文章:文章最上面的那个链接

      本文标题:AngularJS的数据双向绑定是怎么实现的?

      本文链接:https://www.haomeiwen.com/subject/qstvpttx.html