在angularjs1.X 中存在了三种数据绑定的方式,用于数据的同步、展现。在 angularjs 1.3
以前,angularjs
只存在两种方式: two-way-binding
和 one-way-bindng
, 然后则引入了称为one-time-binding
的绑定机制。html
目前angularjs
中存在如下三种数据绑定方式:angularjs
angularjs
中的 Two-way-binding
的做用是将 Model
和 View
关联起来,任何一侧的数据变动都会更新另外一侧的数据。express
常见场景是页面中的输入区域。双向绑定能够很容易的将输入控件的值关联到数据模型中。浏览器
<input type="text" id="text" ng-model="name"/>
经过 ng-model
咱们能够很容易的将输入框(view
)的值和 name
(Model
) 关联起来。在双向数据流的做用下,不管是咱们修改输入框的值仍是修改 name
,另一侧都将及时更新到新数据。app
ng-model
是 angularjs
内置的一个指令用来实现双向绑定。ng-model
在不一样生命周期中,有不一样的逻辑处理。异步
compilation phase:spa
ng-model
指令和 input
指令会被合并处理给 input
标签 注册 keydown
事件(DOM Event);interpolation
则注册一个 $watch
用来订阅 change
事件(angularjs Event)。Runtime Phase双向绑定
keydown
input
指令捕获 keydown
事件,调用 $apply
来请求更新动做。angularjs
更新值到 Model
$digest
上下文$watch
表达式检测到 Model
发生了 change
,通知interpolation
,请求 更新 DOM
。angularjs
托管结束,退出托管,交还控制权到 JavaScript 执行上下文。不一样于 Two-way-binding
的双向流动, one-way-binding
的数据流向是单向,即只会从 model
流向 view
,而不会从 view
流向 model
。 所以, one-way-binding
用来展现数据,而不是获取输入。code
在 angularjs
中, one-way-binding
则有两种语法: ng-bind
和 {{expression}}
。htm
<span ng-bind="name"> </span> <span>{{name}}</span>
对于 one-way-binding
来讲,内部机制和 two-way-binding
有部分相同的机制。
compilation phase:
interpolation
注册一个 $watch
用来订阅 change
事件(angularjs Event)。runtime phase:
angularjs
进入 $digest
。expression
的 $watch
检测到数据发生变动,通知interpolation
,请求 更新 DOM
。angularjs
托管结束,退出托管,交还控制权到 JavaScript 执行上下文。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
能够确认是否要更新数据。
文中不免存在一些错误,欢迎你们斧正。