angularjs 的数据绑定实现原理


Posted in Javascript onJuly 02, 2018

在angularjs1.X 中存在了三种数据绑定的方式,用于数据的同步、展示。在 angularjs 1.3 之前,angularjs 只存在两种方式: two-way-binding 和 one-way-bindng , 而后则引入了称为one-time-binding 的绑定机制。

目前angularjs 中存在以下三种数据绑定方式:

  1. two-way-binding
  2. one-way-binding
  3. one-time-binding

two-way-binding

angularjs 中的 Two-way-binding 的作用是将 Model 和 View 关联起来,任何一侧的数据变更都会更新另一侧的数据。

常见场景是页面中的输入区域。双向绑定可以很容易的将输入控件的值关联到数据模型中。

<input type="text" id="text" ng-model="name"/>

通过 ng-model 我们可以很容易的将输入框(view)的值和 name (Model) 关联起来。在双向数据流的作用下,无论是我们修改输入框的值还是修改 name,另外一侧都将及时更新到新数据。

ng-model 是 angularjs 内置的一个指令用来实现双向绑定。ng-model 在不同生命周期中,有不同的逻辑处理。

1、compilation phase:

  • ng-model 指令和 input 指令会被合并处理给 input 标签 注册 keydown事件(DOM Event);
  • interpolation 则注册一个 $watch 用来订阅 change 事件(angularjs Event)。

2、Runtime Phase

  • 用户输入触发 keydown
  • input 指令捕获 keydown 事件,调用 $apply 来请求更新动作。
  • angularjs 更新值到 Model
  • 进入 $digest 上下文
  • $watch 表达式检测到 Model 发生了 change,通知interpolation ,请求 更新 DOM。
  • angularjs 托管结束,退出托管,交还控制权到 JavaScript 执行上下文。
  • 最后浏览器重新渲染文本。

One-way-binding

不同于 Two-way-binding的双向流动, one-way-binding 的数据流向是单向,即只会从 model 流向 view ,而不会从 view 流向 model。 因此, one-way-binding 用来展示数据,而不是获取输入。

在 angularjs 中, one-way-binding 则有两种语法: ng-bind 和 {{expression}}。

<span ng-bind="name"> </span>
<span>{{name}}</span>

对于 one-way-binding来说,内部机制和 two-way-binding 有部分相同的机制。

1、compilation phase:

  1. interpolation 注册一个 $watch 用来订阅 change 事件(angularjs Event)。

2、runtime phase:

  1. angularjs 进入 $digest 。
  2. expression 的 $watch 检测到数据发生变更,通知interpolation ,请求 更新 DOM。
  3. angularjs 托管结束,退出托管,交还控制权到 JavaScript 执行上下文。
  4. 最后浏览器重新渲染文本。

one-time-binding

1.3 之后,angularjs 实现了一个叫 one-time-binding 的机制。本质上它的机制和其他两种方式没太多差异,但在数据更新时候表现的不太一样。

one-time-binding 同样会注册 $watch 来监听数据变化,但它会在第一次检测到数据 非 Undefined 时候取消监听。

<span>{{::name}}</span>

对于上面的代码,假设 name 从 undefined -> angularjs -> angular ,最终渲染的结果是 angularjs ,而不是 angular 。 这就是 one-time-binding 的特殊之处,当 name 从 undefined 变化为 angularjs之后,被认定为 name 的状态已经是 stable ,因此将取消 $watch , 即不再监听数据变化。

那么,假设 name 从 '' -> angularjs-> angular, 则渲染结果是 '' ,即空字符串(第一次的值)。因为 one-time-binding 在计算 stable 时候使用的 严格相等,即 newVal === undefined, 如果是,则继续保留 $watch 等待下一次的比较;否则,状态变更为 stable,取消 $watch, 数据转化为最终态。

结束

在我看来,angularjs 核心在于 angularjs context 和 $digest 。

angularjs context 保证 angularjs 可以捕获到各种事件,用户输入、鼠标事件、键盘事件、甚至 $settimeout和 $http 等异步行为的状态流转。

而 $digest 则保证 angularjs 可以确认是否要更新数据。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用javascript获得地址栏参数的两种方法
Nov 08 Javascript
ext jquery 简单比较
Apr 07 Javascript
Jquery submit()无法提交问题
Apr 21 Javascript
JS判断表单输入是否为空(示例代码)
Dec 23 Javascript
jQuery的:parent选择器定义和用法
Jul 01 Javascript
jquery实现拖拽调整Div大小
Jan 30 Javascript
解决jquery中动态新增的元素节点无法触发事件问题的两种方法
Oct 30 Javascript
javaScript知识点总结(必看篇)
Jun 10 Javascript
vue.js组件之间传递数据的方法
Jul 10 Javascript
如何选择适合你的JavaScript框架
Nov 20 Javascript
vue.js,ajax渲染页面的实例
Feb 11 Javascript
Vue props用法详解(小结)
Jul 03 Javascript
vue 解决addRoutes动态添加路由后刷新失效问题
Jul 02 #Javascript
vue中的数据绑定原理的实现
Jul 02 #Javascript
Vue实现双向绑定的原理以及响应式数据的方法
Jul 02 #Javascript
jsonp跨域获取数据的基础教程
Jul 01 #Javascript
vue + webpack如何绕过QQ音乐接口对host的验证详解
Jul 01 #Javascript
关于Vue组件库开发详析
Jul 01 #Javascript
D3.js实现拓扑图的示例代码
Jun 30 #Javascript
You might like
SONY SRF-22W(33W)的电路分析和维修案例
2021/03/02 无线电
自定义PHP分页函数
2006/10/09 PHP
自制PHP框架之路由与控制器
2017/05/07 PHP
比较全的JS checkbox全选、取消全选、删除功能代码
2008/12/19 Javascript
Javascript 面向对象特性
2009/12/28 Javascript
分别用marquee和div+js实现首尾相连循环滚动效果,仅3行代码
2011/09/21 Javascript
JQuery加载图片自适应固定大小的DIV
2013/09/12 Javascript
javascript计算用户打开网页的停留时间
2014/01/09 Javascript
jquery提交form表单时禁止重复提交的方法
2014/02/13 Javascript
js或jquery实现页面打印可局部打印
2014/03/27 Javascript
jQuery中noConflict()用法实例分析
2015/02/08 Javascript
jQuery设置和移除文本框默认值的方法
2015/03/09 Javascript
JavaScript中的Math.LOG2E属性使用详解
2015/06/14 Javascript
微信小程序-消息提示框实例
2016/11/24 Javascript
详解如何从零开始搭建Express+Vue开发环境
2018/07/17 Javascript
JS大坑之19位数的Number型精度丢失问题详解
2019/04/22 Javascript
ES6数组与对象的解构赋值详解
2019/06/14 Javascript
vue遍历生成的输入框 绑定及修改值示例
2019/10/30 Javascript
微信小程序商品详情页底部弹出框
2019/11/22 Javascript
在Python的Flask框架下使用sqlalchemy库的简单教程
2015/04/09 Python
python logging日志模块以及多进程日志详解
2018/04/18 Python
解决pyttsx3无法封装的问题
2018/12/24 Python
基于Django的乐观锁与悲观锁解决订单并发问题详解
2019/07/31 Python
使用python写的opencv实时监测和解析二维码和条形码
2019/08/14 Python
使用pytorch实现可视化中间层的结果
2019/12/30 Python
Python如何在windows环境安装pip及rarfile
2020/06/15 Python
Pycharm常用快捷键总结及配置方法
2020/11/14 Python
卡骆驰德国官方网站:Crocs德国
2019/03/29 全球购物
北美最大的零售退货翻新商:VIP Outlet
2019/11/21 全球购物
秘书专业自荐信范文
2013/12/26 职场文书
运动会广播稿500字
2014/01/28 职场文书
大专毕业自我鉴定
2014/02/04 职场文书
实习指导老师评语
2014/04/26 职场文书
同意转租证明
2015/06/24 职场文书
2016年寒假生活小结
2015/10/10 职场文书
写给消防战士们的一封慰问信
2019/10/07 职场文书