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 相关文章推荐
ExtJS 2.0 GridPanel基本表格简明教程
May 25 Javascript
jQuery学习笔记 操作jQuery对象 CSS处理
Sep 19 Javascript
iframe子页面与父页面在同域或不同域下的js通信
May 07 Javascript
js中split和replace的用法实例
Feb 28 Javascript
在JavaScript中操作时间之getUTCDate()方法的使用
Jun 10 Javascript
浅谈javascript的call()、apply()、bind()的用法
Feb 21 Javascript
AngularJS 整理一些优化的小技巧
Aug 18 Javascript
layui导航栏实现代码
May 19 Javascript
js数组实现权重概率分配
Sep 12 Javascript
JavaScript实现重力下落与弹性效果的方法分析
Dec 20 Javascript
JS实现的简单下拉框联动功能示例
May 11 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
May 16 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的chr和ord函数实现字符加减乘除运算实现代码
2011/12/05 PHP
将PHP从5.3.28升级到5.3.29时Nginx出现502错误
2015/05/09 PHP
php商品对比功能代码分享
2015/09/24 PHP
php实现学生管理系统
2020/03/21 PHP
php读取本地json文件的实例
2018/03/07 PHP
gearman中任务的优先级和返回状态实例分析
2020/02/27 PHP
JQuery UI的拖拽功能实现方法小结
2012/03/14 Javascript
javascript模拟select,jselect的方法实现
2012/11/08 Javascript
解决Extjs 4 Panel作为Window组件的子组件时出现双重边框问题
2013/01/11 Javascript
开源的javascript项目Kissy介绍
2014/11/28 Javascript
浅谈重写window对象的方法
2014/12/29 Javascript
一个php+js实时显示时间问题
2015/10/12 Javascript
Bootstrap学习笔记之css样式设计(1)
2016/06/07 Javascript
Vue.js计算属性computed与watch(5)
2016/12/09 Javascript
Three.js基础部分学习
2017/01/08 Javascript
微信小程序项目实践之九宫格实现及item跳转功能
2018/07/19 Javascript
微信小程序之多列表的显示和隐藏功能【附源码】
2018/08/06 Javascript
js实现时分秒倒计时
2019/12/03 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
Windows下安装 node 的版本控制工具 nvm
2020/02/06 Javascript
浅谈Python中数据解析
2015/05/05 Python
python实现计算倒数的方法
2015/07/11 Python
Python+tkinter使用40行代码实现计算器功能
2018/01/30 Python
TensorFlow saver指定变量的存取
2018/03/10 Python
python 读取视频,处理后,实时计算帧数fps的方法
2018/07/10 Python
在双python下设置python3为默认的方法
2018/10/31 Python
Django logging配置及使用详解
2019/07/23 Python
Pycharm 2020年最新激活码(亲测有效)
2020/09/18 Python
详解Python中namedtuple的使用
2020/04/27 Python
python获取命令行参数实例方法讲解
2020/11/02 Python
纯CSS3制作页面切换效果的实例代码
2019/05/30 HTML / CSS
马克华菲官方商城:Mark Fairwhale
2016/09/04 全球购物
GLAMGLOW格莱魅美国官网:美国知名的面膜品牌
2016/12/31 全球购物
美国最大的网上冲印店:Shutterfly
2017/01/01 全球购物
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
三年级评语大全
2014/04/23 职场文书