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 相关文章推荐
IE8 浏览器Cookie的处理
Jan 31 Javascript
jquery 弹出层注册页面等(asp.net后台)
Jun 17 Javascript
javaScript如何生成xmlhttp
Dec 16 Javascript
wap手机图片滑动切换特效无css3元素js脚本编写
Jul 28 Javascript
浅谈Unicode与JavaScript的发展史
Jan 19 Javascript
js图片上传前预览功能(兼容所有浏览器)
Aug 24 Javascript
js通过classname来获取元素的方法
Nov 24 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
Dec 05 Javascript
基于javascript实现最简单选项卡切换
Feb 01 Javascript
jQuery实现Select下拉列表进行状态选择功能
Mar 30 jQuery
浅谈vue项目4rs vue-router上线后history模式遇到的坑
Sep 27 Javascript
vue-cli在 history模式下的配置详解
Nov 26 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
MYSQL数据库初学者使用指南
2006/11/16 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
php实现事件监听与触发的方法
2014/11/21 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
Javascript+XMLHttpRequest+asp.net无刷新读取数据库数据
2009/08/09 Javascript
jQuery中使用data()方法读取HTML5自定义属性data-*实例
2014/04/11 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
jQuery实现的感应鼠标悬停图片色彩渐显效果
2015/03/03 Javascript
jquery事件绑定解绑机制源码解析
2016/09/19 Javascript
vue中如何实现变量和字符串拼接
2017/06/19 Javascript
基于vue打包后字体和图片资源失效问题的解决方法
2018/03/06 Javascript
微信小程序项目实践之验证码倒计时功能
2018/07/18 Javascript
使用Angular material主题定义自己的组件库的配色体系
2019/09/04 Javascript
关于layui toolbar和template的结合使用方法
2019/09/19 Javascript
[02:36]DOTA2混沌骑士 英雄基础教程
2013/11/26 DOTA
从局部变量和全局变量开始全面解析Python中变量的作用域
2016/06/16 Python
各种Python库安装包下载地址与安装过程详细介绍(Windows版)
2016/11/02 Python
Python实现线程状态监测简单示例
2018/03/28 Python
Python基于Opencv来快速实现人脸识别过程详解(完整版)
2019/07/11 Python
python 求定积分和不定积分示例
2019/11/20 Python
Python socket聊天脚本代码实例
2020/01/02 Python
Django 自定义404 500等错误页面的实现
2020/03/08 Python
快速解决Django关闭Debug模式无法加载media图片与static静态文件
2020/04/07 Python
利用Python实现Excel的文件间的数据匹配功能
2020/06/16 Python
基于python实现操作redis及消息队列
2020/08/27 Python
初中英语课后反思
2014/04/25 职场文书
公司租房协议书
2014/10/14 职场文书
2015年学校财务工作总结
2015/05/19 职场文书
2016猴年春节慰问信
2015/11/30 职场文书
CSS3实现的3D隧道效果
2021/04/27 HTML / CSS
Windows中Redis安装配置流程并实现远程访问功能
2021/06/07 Redis
Python机器学习之底层实现KNN
2021/06/20 Python
MySQL约束超详解
2021/09/04 MySQL
动画《新网球王子 U-17 WORLD CUP》希腊队PV公开
2022/04/02 日漫