首頁  >  文章  >  web前端  >  AngularJS中的$watch(),$digest()和$apply()區分_AngularJS

AngularJS中的$watch(),$digest()和$apply()區分_AngularJS

WBOY
WBOY原創
2016-05-16 15:06:361298瀏覽

AngularJS $scope裡面的$watch(),$digest()和$apply()是AngularJS的核心函數,學習AngularJS必須理解這幾個函數。

在綁定$scope中的變數到view的時候,AngularJS會自動在內部建立一個"Watch"。 "Watch"用於監聽AngularJS scope中變數的改變。可以透過呼叫$scope.$watch()這個方法來建立"Watch"。

$scope.$digest()函數會循環存取所有的watches,並偵測其所監聽的$scope中的變數是否改變。如果變數改變,會呼叫該變數對應的監聽函數。監聽函數可以實現很多操作,例如讓html裡面的text文字顯示最新的變數值。可見,$scope.$digest是可以觸發資料綁定更新的。

大部分情況下,AngualrJS會自動呼叫$scope.$watch()和$scope.$digest()函數,但是在某些情況下,我們需要手動呼叫他們,因此,有必要了解他們是怎麼工作的。

$scope.$apply()這個函數會先執行一些程式碼,之後在呼叫$scope.$digest()。所有的watches會被偵測一次,對應的監聽函數也會被執行。 $scope.$apply()在AngularJS與其它javascript程式碼整合時是很有用的。

接下來我們具體的講解下$watch(), $digest() 和 $apply()。

$watch()
$watch(watchExpression, listener, [objectEquality])

watchExpression:監聽對象,可以是string或function(scope){}

listener:監聽物件改變時執行的回呼函數function(newVal,oldVal,scope){}

objectEquality:是否深度監聽,如果設定為true,它告訴Angular檢查所監控的物件中每個屬性的變化。如果你希望監控數組的個別元素或物件的屬性而不是一個普通的值, 那麼你應該使用它。 (預設值:false)

$digest()
偵測目前scope以及子scope中所有的watches,因為監聽函式會在執行過程中修改model(scope中的變數),$digest()會一直被呼叫直到model沒有再變。當呼叫超過10次時,$digest()會拋出一個異常"Maximum iteration limit exceeded',以此來防止程式進入一個死循環。

$apply()
$apply([exp])

exp:string或function(scope){}

$apply()生命週期偽代碼示意圖如下

function $apply(expr) {
 try {
  return $eval(expr);
 } catch (e) {
  $exceptionHandler(e);
 } finally {
  $root.$digest();
 }
}

Example
下面我們透過一個例子來說明$watch,$digest和$apply。

<script>
var module = angular.module("myapp", []);
var myController1 = module.controller("myController", function($scope) {
  $scope.data = { time : new Date() };
  $scope.updateTime = function() {
    $scope.data.time = new Date();
  }
   
  document.getElementById("updateTimeButton")
      .addEventListener('click', function() {
    console.log("update time clicked");
    $scope.data.time = new Date();
  });
});
</script>
<body ng-app="myapp">
<div ng-controller="myController">
  {{data.time}}
 
  <br/>
  <button ng-click="updateTime()">update time - ng-click</button>
  <button id="updateTimeButton" >update time</button>
</div>
</body>

這段程式碼會綁定$scope.data.time到HTML中顯示出來,同時這個綁定會自動建立一個watch來監聽$scope.date.time的變化。此外,這裡還有2個按鈕,第一個按鈕是透過ng-click Directive來呼叫$scope.updateTime方法,之後AngularJS會自動執行$scope.$digest()使最新的時間顯示到HTML中。第二個按鈕是透過javascript程式碼新增一個點擊事件,以此來更新HTML中的時間。但是第二個按鈕是不能工作的,它的解決辦法是在點擊事件的最後手動的去調用$scope.$digest()方法,如下:

document.getElementById("updateTimeButton")
    .addEventListener('click', function() {
  console.log("update time clicked");
  $scope.data.time = new Date();
  $scope.$digest();
});

另外一個解決方法是呼叫$scope.$apply(),如下:

document.getElementById("updateTimeButton")
    .addEventListener('click', function() {
  $scope.$apply(function(){
      console.log("update time clicked");
      $scope.data.time = new Date();
    }
  );
});

以上就是本文的全部內容,希望對大家的學習有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn