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 相关文章推荐
用js解决数字不能换行问题
Aug 10 Javascript
百度地图给map添加右键菜单(判断是否为marker)
Mar 04 Javascript
jQuery调用WebMethod(PageMethod) NET2.0的方法
Apr 15 Javascript
关于vue.js弹窗组件的知识点总结
Sep 11 Javascript
真正好用的js验证上传文件大小的简单方法
Oct 27 Javascript
js仿小米手机上下滑动效果
Feb 05 Javascript
原生JavaScript实现精美的淘宝轮播图效果示例【附demo源码下载】
May 27 Javascript
微信小程序之蓝牙的链接
Sep 26 Javascript
Vue中保存数据到磁盘文件的方法
Sep 06 Javascript
微信小程序生成海报分享朋友圈的实现方法
May 06 Javascript
13 个npm 快速开发技巧(推荐)
Jul 04 Javascript
在博客园博文中添加自定义右键菜单的方法详解
Feb 05 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
在apache下限制每个虚拟主机的并发数!!!!
2006/10/09 PHP
使用Limit参数优化MySQL查询的方法
2008/11/12 PHP
Php图像处理类代码分享
2012/01/19 PHP
使用新浪微博API的OAuth认证发布微博实例
2015/03/27 PHP
php判断当前操作系统类型
2015/10/28 PHP
PHP反射机制原理与用法详解
2017/02/15 PHP
thinkphp5 加载静态资源路径与常量的方法
2017/12/24 PHP
PHP使用正则表达式实现过滤非法字符串功能示例
2018/06/04 PHP
IE中radio 或checkbox的checked属性初始状态下不能选中显示问题
2009/07/25 Javascript
JS与框架页的操作代码
2010/01/17 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
2011/09/13 Javascript
jQuery链式操作实例分析
2015/11/16 Javascript
jquery获取select选中值的方法分析
2015/12/22 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
如何使用headjs来管理和异步加载js
2016/11/29 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
BootStrap Table前台和后台分页对JSON格式的要求
2017/06/28 Javascript
jQuery修改DOM结构_动力节点Java学院整理
2017/07/05 jQuery
javascript按顺序加载运行js方法
2017/12/01 Javascript
vue init webpack myproject构建项目 ip不能访问的解决方法
2018/03/20 Javascript
深入理解js A*寻路算法原理与具体实现过程
2018/12/13 Javascript
jQuery实现的3D版图片轮播示例【滑动轮播】
2019/01/18 jQuery
js this 绑定机制深入详解
2020/04/30 Javascript
[48:28]完美世界DOTA2联赛循环赛FTD vs Magma第二场 10月30日
2020/10/31 DOTA
Python操作MongoDB详解及实例
2017/05/18 Python
Python调用微信公众平台接口操作示例
2017/07/08 Python
python使用生成器实现可迭代对象
2018/03/20 Python
Python实现的FTP通信客户端与服务器端功能示例
2018/03/28 Python
jupyter notebook插入本地图片的实现
2020/04/13 Python
python实例化对象的具体方法
2020/06/17 Python
Dr. Martens马汀博士官网:马丁靴始祖品牌
2016/10/15 全球购物
Interrail法国:乘火车探索欧洲,最受欢迎的欧洲铁路通票
2019/08/27 全球购物
泰国在线书店:SE-ED
2020/06/21 全球购物
abstract class和interface有什么区别
2013/08/04 面试题
媒体宣传策划方案
2014/05/25 职场文书
小学运动会宣传稿
2015/07/23 职场文书