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 UI 使用心得及技巧
Oct 10 Javascript
JSuggest自动匹配下拉框使用方法(示例代码)
Dec 27 Javascript
js 设置缓存及获取设置的缓存
May 08 Javascript
JQuery实现table行折叠效果以JSON做数据源
May 26 Javascript
Node.js实现文件上传
Jul 05 Javascript
js操作DOM--添加、删除节点的简单实例
Jul 08 Javascript
微信小程序button组件使用详解
Jan 31 Javascript
代码详解javascript模块加载器
Mar 04 Javascript
浅谈Node.js 中间件模式
Jun 12 Javascript
解决layui中onchange失效以及form动态渲染失效的问题
Sep 27 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
Jul 19 Javascript
node.js爬虫框架node-crawler初体验
Oct 29 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者的疑难问答(2)
2006/10/09 PHP
追求程序速度,而不是编程的速度
2008/04/23 PHP
php sprintf()函数让你的sql操作更安全
2008/07/23 PHP
PHP 获取远程文件内容的函数代码
2010/03/24 PHP
thinkphp连贯操作实例分析
2014/11/22 PHP
PHP 多进程与信号中断实现多任务常驻内存管理实例方法
2019/10/04 PHP
Whatever:hover 无需javascript让IE支持丰富伪类
2010/06/29 Javascript
jquery获取自定义属性(attr和prop)实例介绍
2013/04/21 Javascript
Jquery加载时从后台读取数据绑定到dropdownList实例
2013/06/09 Javascript
javascript实现多级联动下拉菜单的方法
2015/02/06 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
javascript鼠标跟随运动3种效果(眼球效果,苹果菜单,方向跟随)
2016/10/27 Javascript
浅谈JavaScript事件绑定的常用方法及其优缺点分析
2016/11/01 Javascript
Angular.JS判断复选框checkbox是否选中并实时显示
2016/11/30 Javascript
webpack入门+react环境配置
2017/02/08 Javascript
JavaScript基于扩展String实现替换字符串中index处字符的方法
2017/06/13 Javascript
JavaScript实现的数字与字符串转换功能示例
2017/08/23 Javascript
5 种JavaScript编码规范
2018/01/30 Javascript
angular6.0开发教程之如何安装angular6.0框架
2018/06/29 Javascript
ES6 迭代器与可迭代对象的实现
2019/02/11 Javascript
基于javascript实现日历功能原理及代码实例
2020/05/07 Javascript
vue接通后端api以及部署到服务器操作
2020/08/13 Javascript
详解vite2.0配置学习(typescript版本)
2021/02/25 Javascript
[41:12]Liquid vs Secret 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.24
2019/09/10 DOTA
Python实现PS图像调整颜色梯度效果示例
2018/01/25 Python
Python生成指定数量的优惠码实操内容
2019/06/18 Python
Python坐标线性插值应用实现
2019/11/13 Python
详解Python Opencv和PIL读取图像文件的差别
2019/12/27 Python
html5如何在Canvas中实现自定义路径动画示例
2017/09/18 HTML / CSS
基于canvas的骨骼动画的示例代码
2018/06/12 HTML / CSS
高级人员简历的自我评价分享
2013/11/03 职场文书
公司同意接收函
2014/01/13 职场文书
甜品蛋糕店创业计划书范文
2014/02/06 职场文书
地方白酒代理协议书
2014/10/25 职场文书
2015年检验科工作总结
2015/04/27 职场文书
Redis数据同步之redis shake的实现方法
2022/04/21 Redis