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获取文本框中字符长度的代码
Sep 29 Javascript
jQuery-Easyui 1.2 实现多层菜单效果的代码
Jan 13 Javascript
HTML中的setCapture和releaseCapture使用介绍
Mar 21 Javascript
JSONP跨域的原理解析及其实现介绍
Mar 22 Javascript
jQuery中end()方法用法实例
Jan 08 Javascript
JS点击链接后慢慢展开隐藏着图片的方法
Feb 17 Javascript
详解Javascript中prototype属性(推荐)
Sep 03 Javascript
AngularJS解决ng-if中的ng-model值无效的问题
Jun 21 Javascript
Angular中支持SCSS的方法
Nov 18 Javascript
vue 使用eventBus实现同级组件的通讯
Mar 02 Javascript
js中async函数结合promise的小案例浅析
Apr 14 Javascript
js实现头像上传并且可预览提交
Dec 25 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
PHP中去掉字符串首尾空格的方法
2012/05/19 PHP
Laravel 4.2 中队列服务(queue)使用感受
2014/10/30 PHP
分享PHP计算两个日期相差天数的代码
2015/12/23 PHP
php进程间通讯实例分析
2016/07/11 PHP
php+js实现点赞功能的示例详解
2020/08/07 PHP
关于jquery动态增减控件的一些想法和小插件
2010/08/01 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
JavaScript+CSS实现仿天猫侧边网页菜单效果
2015/08/25 Javascript
Javascript编程中几种继承方式比较分析
2015/11/28 Javascript
AngularJS 模块化详解及实例代码
2016/09/14 Javascript
Vue 组件间的样式冲突污染
2017/08/31 Javascript
nodejs实现爬取网站图片功能
2017/12/14 NodeJs
如何为vuex实现带参数的 getter和state.commit
2019/01/04 Javascript
Python调用C语言开发的共享库方法实例
2015/03/18 Python
python计算牛顿迭代多项式实例分析
2015/05/07 Python
分数霸榜! python助你微信跳一跳拿高分
2018/01/08 Python
python爬虫之模拟登陆csdn的实例代码
2018/05/18 Python
对django 2.x版本中models.ForeignKey()外键说明介绍
2020/03/30 Python
JAVA及PYTHON质数计算代码对比解析
2020/06/10 Python
详解python UDP 编程
2020/08/24 Python
Python识别处理照片中的条形码
2020/11/16 Python
世界著名的顶级牛排:Omaha Steak(奥马哈牛排)
2016/09/20 全球购物
Fabletics官网:美国运动服饰品牌,由好莱坞女演员凯特·哈德森创立
2019/10/19 全球购物
加拿大专业美发产品购物网站:Chatters
2021/02/28 全球购物
大学毕业生工作的自我评价
2013/10/01 职场文书
幼儿园长自我鉴定
2013/10/17 职场文书
小学岗位竞聘方案
2014/01/22 职场文书
经典安踏广告词
2014/03/21 职场文书
保护环境的标语
2014/06/09 职场文书
体育课外活动总结
2014/07/08 职场文书
奥巴马当选演讲稿
2014/09/10 职场文书
2015年端午节活动总结
2015/02/11 职场文书
党员年度个人总结
2015/02/14 职场文书
最新的离婚协议书范本!
2019/07/02 职场文书
python简单验证码识别的实现过程
2021/06/20 Python
JS实现刷新网页后之前浏览位置保持不变示例详解
2022/08/14 Javascript