在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
能夠確認是否要更新數據。
文中不免存在一些錯誤,歡迎你們斧正。