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 相关文章推荐
IE Firefox 使用自定义标签的区别
Oct 15 Javascript
JavaScript Event学习第十一章 按键的检测
Feb 10 Javascript
中文输入法不触发onkeyup事件的解决办法
Jul 09 Javascript
jQuery实现tag便签去重效果的方法
Jan 20 Javascript
Java File类的常用方法总结
Mar 18 Javascript
js style.display=block显示布局错乱问题的解决方法
Sep 21 Javascript
JavaScript基本类型值-Number类型
Feb 24 Javascript
three.js绘制地球、飞机与轨迹的效果示例
Feb 28 Javascript
jQuery插件zTree实现清空选中第一个节点所有子节点的方法
Mar 08 Javascript
详谈Node.js之操作文件系统
Aug 29 Javascript
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
Sep 14 Javascript
layui扩展上传组件模拟进度条的方法
Sep 23 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
Laravel-添加后台模板AdminLte的实现方法
2019/10/08 PHP
Javascript实例教程(19) 使用HoTMetal(1)
2006/12/23 Javascript
不间断滚动JS打包类,基本可以实现所有的滚动效果,太强了
2007/12/08 Javascript
关于JavaScript的with 语句的使用方法
2011/05/09 Javascript
调试Node.JS的辅助工具(NodeWatcher)
2012/01/04 Javascript
JS对象与JSON格式数据相互转换
2012/02/20 Javascript
jquery插件冲突(jquery.noconflict)解决方法分享
2014/03/20 Javascript
js完美解决IE6不支持position:fixed的bug
2015/04/24 Javascript
基于jquery实现放大镜效果
2015/08/17 Javascript
JS实现仿FLASH效果的竖排导航代码
2015/09/15 Javascript
JSON简介以及用法汇总
2016/02/21 Javascript
全面解析Bootstrap中form、navbar的使用方法
2016/05/30 Javascript
浅谈javascript中的加减时间
2016/07/12 Javascript
JavaScript排序算法动画演示效果的实现方法
2016/10/18 Javascript
vue.js2.0点击获取自己的属性和jquery方法
2018/02/23 jQuery
vue源码学习之Object.defineProperty 对数组监听
2018/05/30 Javascript
小程序云函数调用API接口的方法
2019/05/17 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
2020/07/26 Javascript
微信小程序实现多行文字滚动
2020/11/18 Javascript
Python解析nginx日志文件
2015/05/11 Python
Python中逗号的三种作用实例分析
2015/06/08 Python
Python 类的继承实例详解
2017/03/25 Python
python+opencv轮廓检测代码解析
2018/01/05 Python
python实现媒体播放器功能
2018/02/11 Python
Python爬虫框架Scrapy常用命令总结
2018/07/26 Python
使用Python如何测试InnoDB与MyISAM的读写性能
2018/09/18 Python
详解Python使用Plotly绘图工具,绘制甘特图
2019/04/02 Python
浅析python 定时拆分备份 nginx 日志的方法
2020/04/27 Python
Html5移动端弹幕动画实现示例代码
2018/08/27 HTML / CSS
.NET常见笔试题集
2012/12/01 面试题
人力资源管理系自荐信
2014/05/31 职场文书
村党支部书记四风问题个人对照检查材料思想汇报
2014/10/06 职场文书
总账会计岗位职责
2015/04/02 职场文书
Go归并排序算法的实现方法
2022/04/06 Golang
WINDOWS下安装mysql 8.x 的方法图文教程
2022/04/19 MySQL