資料繫結示例
<p ng-bind="message"></p>
此訊息必須附加到當前元素控制器的範圍。
$scope.message = "Hello World";
在以後的某個時間點,即使更新了訊息模型,該更新的值也會反映在 HTML 元素中。當角度編譯模板時,Hello World
將附加到當前世界的 innerHTML。Angular 維護著一個附加到檢視的所有指令的監視機制。它有一個 Digest Cycle 機制,它遍歷 Watchers 陣列,如果模型的先前值發生變化,它將更新 DOM 元素。
沒有定期檢查 Scope 是否附加的物件有任何變化。並非所有附加到範圍的物件都被觀看。範圍原型維護 $$ WatchersArray 。只有在呼叫$ digest 時,Scope 才會遍歷此 WatchersArray。
Angular 為 WatchersArray 新增了一個觀察者
- {{表示式}} - 在你的模板中(以及其他任何有表示式的地方)或我們定義 ng-model 時。
- $ scope。$ watch(’expression / function’) - 在你的 JavaScript 中,我們可以附加一個範圍物件來觀察角度。
$ watch 函式有三個引數:
- 第一個是觀察者函式,它只返回物件,或者我們可以新增一個表示式。
- 第二個是偵聽器函式,當物件發生更改時將呼叫該函式。DOM 更改等所有內容都將在此函式中實現。
- 第三個是可選引數,它接受一個布林值。如果它是真的,有角度的深度觀察物件&如果它的假角度只是做一個參考觀察物件。 $ watch 的粗略實現看起來像這樣
Scope.prototype.$watch = function(watchFn, listenerFn) {
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() { },
last: initWatchVal // initWatchVal is typically undefined
};
this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers
};
Angular 中有一個有趣的東西叫做 Digest Cycle。 $ digest 迴圈由於呼叫$ scope 而開始。$ digest()
。假設你通過 ng-click 指令更改處理函式中的$ scope 模型。在這種情況下,AngularJS 通過呼叫$ digest()
自動觸發$ digest 迴圈。除了 ng-click 之外,還有其他一些內建指令/服務可以讓你改變模型(例如 ng-model,$ timeout 等)並自動觸發$ digest 迴圈。 $ digest 的粗略實現看起來像這樣。
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = this.$$digestOnce();
} while (dirty);
}
Scope.prototype.$$digestOnce = function() {
var self = this;
var newValue, oldValue, dirty;
_.forEach(this.$$watchers, function(watcher) {
newValue = watcher.watchFn(self);
oldValue = watcher.last; // It just remembers the last value for dirty checking
if (newValue !== oldValue) { //Dirty checking of References
// For Deep checking the object , code of Value
// based checking of Object should be implemented here
watcher.last = newValue;
watcher.listenerFn(newValue,
(oldValue === initWatchVal ? newValue : oldValue),
self);
dirty = true;
}
});
return dirty;
};
如果我們使用 JavaScript 的 setTimeout()
函式來更新範圍模型,Angular 無法知道你可能會更改什麼。在這種情況下,我們有責任手動呼叫$ apply()
,這會觸發$ digest 迴圈。類似地,如果你有一個設定 DOM 事件偵聽器的指令並更改處理函式內部的某些模型,則需要呼叫$ apply()
以確保更改生效。 $ apply 的主要思想是我們可以執行一些不瞭解 Angular 的程式碼,該程式碼可能仍會改變範圍內的東西。如果我們將該程式碼包裝在$ apply 中,它將負責呼叫$ digest()
。 $ apply()
的粗略實現。
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};