Angular数据绑定机制原理


Posted in Javascript onApril 17, 2018

1.Angular.js扩展浏览器的事件循环

浏览器持续等待例如用户交互这样的事件。当你在一个<input>标签里输入字符之后,这个事件的回调函数在JS解释器中执行了其包含的DOM操作,执行完毕后,浏览器响应地对DOM做出了变化。Angular拓展了这个事件循环,使它有时候成为angular context 的执行环境。

2.$watch list

$watch 可以检测model的变化。每当绑定一个数据到view上的时候,$watch队列就会插入一条对应的$watch。例子如下:

controller.js:

app.controller('MainCtrl', function($scope) {
 $scope.people = [...]; // 假设长度为10
});

index.html:

<ul>
 <li ng-repeat="person in people">
   {{person.name}} - {{person.age}}
 </li>
</ul>

其中ng-repeat 生成了一个1个$watch,每个person生成了2个$watch,总共是(1+2*10),21个$watch。$watch的生成阶段是模板加载完成,也就是linking阶段。(angular分为compile和linking阶段),Angular会寻找每个directive(上面的例子中ng-repeat和{{}}都属于directive),然后生成每个$watch。

3.$digest 循环

当浏览器接收到angular context相关的事件时,$digest循环就会被触发。它由2个小循环组成,1个处理evalAsync 队列,另一个处理$watch队列。$digest进行循环时,将遍历$watch队列,查看是否有数据更新过,这种遍历就叫做dirty-checkin(脏检查),如果脏检查发现有$watch更新,将会触发新的脏检查,直到所有的$watch都没有更新。这样就能保证每个model都不会变化。

脏检查超过10次后会抛出异常防止无限循环。$digest循环结束后DOM会相应地发生变化。其实$digest从字面意义理解就像“消化”的过程一样,逐渐地把所有营养($watch的变化)都吸收掉。

4.通过$apply 进入 angular context

$apply 决定事件是否进入angular context,使用angualr的自带directive,比如ng-model,更改绑定的数据时,angular会将事件封装到$apply中。比如,ng-model="name"的输入框,输入字符“w”,事件会调用,$apply("name='w';"),完成$scope中的数据更新。

调用第三方库时的数据绑定

当在angular中调用jquery,并不能更新jquery绑定的数据,因为jquery没有调用$apply,事件没有进入angular context,导致$digest没有执行。例子如下:

app.js

app.directive('clickable', function() {
  return {
   restrict: "E",
   scope: {
    count1: '=',
    count2: '='
   },
   template: '<ul style="background-color: lightblue"><li>{{count1}}</li><li>{{count2}}</li></ul>',
   link: function(scope, element, attrs) {
    element.bind('click', function() {
     scope.count1++;
     scope.count2++;
    });
   }
  }
});
app.controller('MainCtrl', function($scope) {
 $scope.count1= 0;
 $scope.count2= 0;
});

例子中,每次点击该元素,预期count1和count2都会自增1,但实际没有。其实$scope(ViewModel)已经改变,但是没有强制执行$digest。修改click事件如下:

element.bind('click', function() {
 scope.$apply(function() {
   scope.foo++;
   scope.bar++;
 });
})

经过调用$apply实现了预期。

5.总结

angular事件绑定机制如下图:

Angular数据绑定机制原理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery text,radio,checkbox,select操作实现代码
Jul 09 Javascript
JavaScript的public、private和privileged模式
Dec 28 Javascript
JQuery球队选择实例
May 18 Javascript
AngularJS初始化静态模板详解
Jan 14 Javascript
javascript中对Date类型的常用操作小结
May 19 Javascript
jQuery图片瀑布流的简单实现代码
Mar 15 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
Sep 06 Javascript
Angular 容器部署的方法
Apr 17 Javascript
创建Vue项目以及引入Iview的方法示例
Dec 03 Javascript
理理Vue细节(推荐)
Apr 16 Javascript
微信小程序Echarts覆盖正常组件问题解决
Jul 13 Javascript
详解如何在Javascript和Sass之间共享变量
Nov 13 Javascript
基于vue-ssr的静态网站生成器VuePress 初体验
Apr 17 #Javascript
jQuery实现使用sort方法对json数据排序的方法
Apr 17 #jQuery
jQuery+datatables插件实现ajax加载数据与增删改查功能示例
Apr 17 #jQuery
jQuery实现带右侧索引功能的通讯录示例【附源码下载】
Apr 17 #jQuery
Angular 容器部署的方法
Apr 17 #Javascript
bootstrap中日历范围选择插件daterangepicker的使用详解
Apr 17 #Javascript
jQuery简单判断值是否存在于数组中的方法示例
Apr 17 #jQuery
You might like
收音机术语解释
2021/03/01 无线电
php处理斐波那契数列非递归方法
2012/02/04 PHP
php加密算法之实现可逆加密算法和解密分享
2014/01/21 PHP
Laravel框架路由配置总结、设置技巧大全
2014/09/03 PHP
php中smarty模板条件判断用法实例
2015/06/11 PHP
CI映射(加载)数据到view层的方法
2016/03/28 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
2018/02/07 PHP
jQuery对象和DOM对象使用说明
2010/06/25 Javascript
JQuery中层次选择器用法实例详解
2015/05/18 Javascript
js数组常见操作及数组与字符串相互转化实例详解
2015/11/10 Javascript
js获取本机操作系统类型的两种方法
2015/12/19 Javascript
原生 JS Ajax,GET和POST 请求实例代码
2016/06/08 Javascript
浅析ES6的八进制与二进制整数字面量
2016/08/30 Javascript
分享Bootstrap简单表格、表单、登录页面
2017/08/04 Javascript
微信小程序引用公共js里的方法的实例详解
2017/08/17 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
Jquery滑动门/tab切换实现方法完整示例
2020/06/05 jQuery
在vue中使用Base64转码的案例
2020/08/07 Javascript
[50:02]完美世界DOTA2联赛循环赛 Magma vs IO BO2第一场 11.01
2020/11/02 DOTA
自己编程中遇到的Python错误和解决方法汇总整理
2015/06/03 Python
举例讲解Python设计模式编程中对抽象工厂模式的运用
2016/03/02 Python
Python实现SSH远程登陆,并执行命令的方法(分享)
2017/05/08 Python
微信跳一跳辅助python代码实现
2018/01/05 Python
特征脸(Eigenface)理论基础之PCA主成分分析法
2018/03/13 Python
python实现邮件发送功能
2019/08/10 Python
Python urllib.request对象案例解析
2020/05/11 Python
python os.rename实例用法详解
2020/12/06 Python
乌克兰在线商店的价格比较:Price.ua
2019/07/26 全球购物
实习求职信
2013/12/01 职场文书
村容村貌整治方案
2014/05/21 职场文书
卫生标语大全
2014/06/21 职场文书
投资公司董事长岗位职责
2015/04/16 职场文书
求职自荐信该如何书写?
2019/06/24 职场文书
python编写函数注意事项总结
2021/03/29 Python