angular.js实现数据双向通信的原理详细介绍
angular.js实现数据双向通信的原理
angular的核心特性有:mvvm、模块化、依赖注入、自动化双向数据绑定、语义标签等。
1、angularjs的scopes对象
angularjs的scopes对象,是一般的javascript对象,可以在他们上面绑定属性和其他对象,也可以添加一些功能,用于观察数据结构上的变化。观察功能都由dirty-checking来实现,并且都在一个digest循环中被执行。
2、angular.js主要通过scopes实现数据双向绑定,scopes包括四个主要部分:
a、digest循环以及dirty-checking,包括watch digest $apply
b、scope继承,这项机制使得我们可以创建scope继承来分享数据和事件
c、集合(数组和对象),有效的dirty-checking
d、事件(on),on emit $broadcast
3、上面的a是用来实现数据的双向绑定的原理,下面主要讲解a
a、事件循环和angular.js扩展
浏览器一直在等待指定事件的响应,比如下面的事件:
● dom事件,譬如用户输入文本,点击按钮等(ng-click)
● xhr响应事件($http)
● 浏览器location变更事件($location)
● timer事件($timeout,$interval)
一旦有指定的事件触发,事件的回调函数就会在javascript的解析器里面执行,然后就可以做任何的dom操作。等回调函数执行完毕时,浏览器就会相应的对dom作出变化。
angular.js拓展了这个事件循环,生成一个有时成为angular context的执行环境。
b、watch队列(watch list)
每次绑定一些东西到ui上时,就会往$watch队列里面插入一条$watch,想象一下$watch就是那个可以检测、监视的model里有变化的东西。当模板加载完成时,也就是在linking阶段(angular分为compole阶段和linking阶段),angular注释器会寻找每个directive,然后生成每个需要的$watch。
c、$digest循环
在a步骤中有提到angular.js扩展循环事件,当浏览器接收到可以被angular context处理的事件时,digest循环就会触发。
digest循环有两部分组成:
● 一个处理evalasync队列
● 另一个处理watch队列
digest将会遍历我们的watch,然后询问他是否有属性和值变化,直到$watch队列都检查过。
这就是所谓的dirty-checking。当$watch有更新过,这个循环就会再次触发,直到所有的$watch都没有变化。这样就能够保证每个model都不变化了。如果循环超过10次,将会抛出一个异常,防止无限循环。当$digest循环结束时,dom相应的变化。
d、通过$apply来进入angular context
$apply决定哪些事件进入angular context,哪些事件不进入。
当指定事件触发时,调用apply,然后进入angular context,如果没调用就不会进入angular context,$digest永远不会执行。