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 字符串连接[性能比较]
May 10 Javascript
使用js写的一个简易的投票
Nov 27 Javascript
php is_numberic函数造成的SQL注入漏洞
Mar 10 Javascript
Javascript WebSocket使用实例介绍(简明入门教程)
Apr 16 Javascript
JS获取下拉框显示值和判断单选按钮的方法
Jul 09 Javascript
jQuery ajax全局函数处理session过期后的ajax跳转问题
Jun 03 Javascript
canvas 绘制圆形时钟
Feb 22 Javascript
Vim快速合并行及vim 将文件所有行合并到一行
Nov 27 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
Jan 25 Javascript
Vue2.0 v-for filter列表过滤功能的实现
Sep 07 Javascript
在vue中使用eslint,配合vscode的操作
Nov 09 Javascript
Vue如何跨组件传递Slot的实现
Dec 14 Vue.js
基于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
德生1994机评
2021/03/02 无线电
fgetcvs在linux的问题
2012/01/15 PHP
如何使用PHP实现javascript的escape和unescape函数
2013/06/29 PHP
PHP eval函数使用介绍
2013/12/08 PHP
PHP检测移动设备类mobile detection使用实例
2014/04/14 PHP
Discuz7.2版的faq.php SQL注入漏洞分析
2014/08/06 PHP
以文件形式缓存php变量的方法
2015/06/26 PHP
php上传大文件设置方法
2016/04/14 PHP
php安全配置记录和常见错误梳理(总结)
2017/03/28 PHP
Jsonp 跨域的原理以及Jquery的解决方案
2011/06/27 Javascript
工作需要写的一个js拖拽组件
2011/07/28 Javascript
jQuery内置的AJAX功能和JSON的使用实例
2014/07/27 Javascript
[原创]JavaScript语法高亮插件highlight.js用法详解【附highlight.js本站下载】
2016/11/01 Javascript
nodeJs实现基于连接池连接mysql的方法示例
2018/02/10 NodeJs
JavaScript获取移动设备型号的实现代码(JS获取手机型号和系统)
2018/03/10 Javascript
jQuery length 和 size()区别总结
2018/04/26 jQuery
150行Node.js实现的dns代理工具
2019/08/02 Javascript
JS实现简单的表格增删
2020/01/16 Javascript
Javascript查看大图功能代码实现
2020/05/07 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
2020/07/26 Javascript
Python多进程写入同一文件的方法
2019/01/14 Python
Python 中包/模块的 `import` 操作代码
2019/04/22 Python
Python CVXOPT模块安装及使用解析
2019/08/01 Python
关于pytorch中网络loss传播和参数更新的理解
2019/08/20 Python
解决Tensorflow占用GPU显存问题
2020/02/03 Python
使用Python爬取Json数据的示例代码
2020/12/07 Python
M1芯片安装python3.9.1的实现
2021/02/02 Python
html5使用canvas实现弹幕功能示例
2017/09/11 HTML / CSS
CK加拿大官网:Calvin Klein加拿大
2020/03/14 全球购物
减负增效提质方案
2014/05/23 职场文书
公司总经理任命书
2014/06/05 职场文书
煤矿安全生产标语
2014/06/06 职场文书
员工考勤管理制度
2015/08/06 职场文书
党员反腐倡廉学习心得体会
2015/08/15 职场文书
Python爬虫数据的分类及json数据使用小结
2021/03/29 Python
Windows下使用Nginx+Tomcat做负载均衡的完整步骤
2021/03/31 Servers