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 相关文章推荐
Javascript select下拉框操作常用方法
Nov 09 Javascript
javascript回车完美实现tab切换功能
Mar 13 Javascript
javascript的解析执行顺序在各个浏览器中的不同
Mar 17 Javascript
javascript冒泡排序小结
Apr 10 Javascript
node.js路径处理方法以及绝对路径详解
Mar 04 Javascript
JS字符串false转boolean的方法(推荐)
Mar 08 Javascript
React中this丢失的四种解决方法
Mar 12 Javascript
微信小程序使用车牌号输入法的示例代码
Aug 20 Javascript
iview form清除校验状态的实现
Sep 19 Javascript
vue获取data数据改变前后的值方法
Nov 07 Javascript
JavaScript遍历数组的方法代码实例
Jan 14 Javascript
VSCode launch.json配置详细教程
Jun 18 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
Drupal7中常用的数据库操作实例
2014/03/02 PHP
PHP中copy on write写时复制机制介绍
2014/05/13 PHP
微信公众平台开发关注及取消关注事件的方法
2014/12/23 PHP
php实现的简单中文验证码功能示例
2017/01/03 PHP
PDO::errorInfo讲解
2019/01/28 PHP
laravel实现上传图片的两种方式小结
2019/10/12 PHP
js 编写规范
2010/03/03 Javascript
javascript 模式设计之工厂模式学习心得
2010/04/27 Javascript
jquery ajax 同步异步的执行示例代码
2010/06/23 Javascript
当jQuery1.7遇上focus方法的问题
2014/01/26 Javascript
自己动手手写jQuery插件总结
2015/01/20 Javascript
angularJS 中$attrs方法使用指南
2015/02/09 Javascript
微信小程序-获得用户输入内容
2017/02/13 Javascript
jacascript DOM节点——元素节点、属性节点、文本节点
2017/04/18 Javascript
Node.js连接mongodb实例代码
2017/06/06 Javascript
Angular项目中$scope.$apply()方法的使用详解
2017/07/26 Javascript
Angular中管道操作符(|)的使用方法
2017/12/15 Javascript
JavaScript怎样在删除前添加确认弹出框?
2019/05/27 Javascript
Node.js API详解之 repl模块用法实例分析
2020/05/25 Javascript
JS实现百度搜索框
2021/02/25 Javascript
Python3 能振兴 Python的原因分析
2014/11/28 Python
十个Python程序员易犯的错误
2015/12/15 Python
python3 selenium自动化 下拉框定位的例子
2019/08/23 Python
使用Fabric自动化部署Django项目的实现
2019/09/27 Python
python获取全国城市pm2.5、臭氧等空气质量过程解析
2019/10/12 Python
python自动化unittest yaml使用过程解析
2020/02/03 Python
解决echarts中饼图标签重叠的问题
2020/05/16 Python
Python list和str互转的实现示例
2020/11/16 Python
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
const和static readonly区别
2013/05/20 面试题
一套比较完整的软件测试人员面试题
2012/05/13 面试题
生物技术研究生自荐信
2013/11/12 职场文书
应届毕业生个人自荐信范文
2013/11/30 职场文书
应用化学专业职业生涯规划书
2013/12/31 职场文书
学校党员个人问题整改措施思想汇报
2014/10/08 职场文书
Vue组件更新数据v-model不生效的解决
2022/04/02 Vue.js