資料繫結示例

<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 新增了一個觀察者

  1. {{表示式}} - 在你的模板中(以及其他任何有表示式的地方)或我們定義 ng-model 時。
  2. $ scope。$ watch(’expression / function’) - 在你的 JavaScript 中,我們可以附加一個範圍物件來觀察角度。

$ watch 函式有三個引數:

  1. 第一個是觀察者函式,它只返回物件,或者我們可以新增一個表示式。
  1. 第二個是偵聽器函式,當物件發生更改時將呼叫該函式。DOM 更改等所有內容都將在此函式中實現。
  1. 第三個是可選引數,它接受一個布林值。如果它是真的,有角度的深度觀察物件&如果它的假角度只是做一個參考觀察物件。 $ 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();
       }
};