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 相关文章推荐
JS中字符问题(二进制/十进制/十六进制及ASCII码之间的转换)
Nov 03 Javascript
jquery判断元素是否隐藏的多种方法
May 06 Javascript
JavaScript bold方法入门实例(把指定文字显示为粗体)
Oct 17 Javascript
JavaScript学习笔记之定时器
Jan 22 Javascript
js实现StringBuffer的简单实例
Sep 02 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
Apr 26 Javascript
基于AngularJS实现表单验证功能
Jul 28 Javascript
使用JQuery实现图片轮播效果的实例(推荐)
Oct 24 jQuery
微信小程序实现图片上传功能
May 28 Javascript
D3.js 实现带伸缩时间轴拓扑图的示例代码
Jan 20 Javascript
vue实现公告栏文字上下滚动效果的示例代码
Jun 16 Javascript
浅谈vue 组件中的setInterval方法和window的不同
Jul 30 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
php计算两个整数的最大公约数常用算法小结
2015/03/05 PHP
php实现按天数、星期、月份查询的搜索框
2016/05/02 PHP
CentOS系统中PHP安装扩展的方式汇总
2017/04/09 PHP
jquery学习笔记 用jquery实现无刷新登录
2011/08/08 Javascript
JS获取鼠标坐标的实例方法
2013/07/18 Javascript
对frameset、frame、iframe的js操作示例代码
2013/08/16 Javascript
Jquery 获取指定标签的对象及属性的设置与移除
2014/05/29 Javascript
深入分析JSONP跨域的原理
2014/12/10 Javascript
JavaScript中常见获取元素的方法汇总
2015/03/04 Javascript
让JavaScript中setTimeout支持链式操作的方法
2015/06/19 Javascript
JS实现的简洁二级导航菜单雏形效果
2015/10/13 Javascript
JS与jQuery实现隔行变色的方法
2016/09/09 Javascript
详解js中==与===的区别
2017/01/08 Javascript
React快速入门教程
2017/01/17 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
2017/08/14 jQuery
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
axios 处理 302 状态码的解决方法
2018/04/10 Javascript
JS实现二维数组横纵列转置的方法
2018/04/17 Javascript
vue.js 图片上传并预览及图片更换功能的实现代码
2018/08/27 Javascript
在vue中实现点击选择框阻止弹出层消失的方法
2018/09/15 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
vue项目部署到nginx/tomcat服务器的实现
2019/08/26 Javascript
[03:58]2014DOTA2国际邀请赛 龙宝赛后解密DK获胜之道
2014/07/14 DOTA
浅谈Python中chr、unichr、ord字符函数之间的对比
2016/06/16 Python
Python 基础知识之字符串处理
2017/01/06 Python
opencv python 2D直方图的示例代码
2018/07/20 Python
python 使用re.search()筛选后 选取部分结果的方法
2018/11/28 Python
Python中logging实例讲解
2019/01/17 Python
HTML5的标签的代码的简单介绍 HTML5标签的简介
2012/05/28 HTML / CSS
html5画布旋转效果示例
2014/01/27 HTML / CSS
美国Randolph太阳镜官网:美国制造的飞行员太阳镜和射击眼镜
2018/06/15 全球购物
荷兰家电购物网站:Expert.nl
2020/01/18 全球购物
外语系毕业生找工作的求职信
2013/11/28 职场文书
培训讲师邀请函
2014/01/10 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书
吉利入股戴姆勒后smart“长大了”
2022/04/21 数码科技