$apply()
?AngularJS 只會關心在 AngularJS 的執行上下文中
發生的數據模型(model)的變化(好比: 改變數據的代碼在 $apply()
裏面)。AngularJS 內建的指令
也會自動觸發 $digest
循環, 因此任何數據模型(model)的改變也都會反映到視圖中。 可是, 若是更改一個 不在 AngularJS 執行上下文中
的數據模型(model), 就須要人爲的調用 $apply()
來提醒 AngularJS 數據發生變化了。javascript
例如, 但使用JavaScript的 setTimeout()
函數來更新一個數據模型的時候, AngularJS 就沒有辦法知道你改變了數據模型。這種狀況下, 就須要調用 $apply()
來觸發 $digest
循環了。相似的, 若是自定義了一個指令, 這個指令設置了一個 DOM 事件監聽器, 更改數據模型的代碼在時間處理函數裏, 那麼也須要調用 $apply()
來保證更改能反映出來。html
DEMO:java
HTML 代碼:app
<!DOCTYPE html> <html lang="en"> <head> <title>demo</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <div ng-app="myApp"> <div ng-controller="myController"> Delayed Message: {{message}} </div> </div> <script src="js/angular.js"> </script> <script src="js/apply.js"></script> </body> </html>
JS 代碼:函數
var myApp = angular.module('myApp', []) myApp.controller('myController', ['$scope', '$timeout', function($scope, $timeout) { $scope.getMessage = function() { // 方法1: setTimeout(function() { // 把須要寫的邏輯放入$apply函數內 $scope.$apply(function() { $scope.message = 'Fetched after 3 seconds' console.log('message: ', $scope.message); }) }, 2000) // 方法2: // $timeout(function() { // $scope.message = 'Fetched after 3 seconds' // console.log('message: ', $scope.message); // }, 2000) // 方法3: // setTimeout(function() { // $scope.message = 'Fetched after 3 seconds' // console.log('message: ', $scope.message); // $scope.$apply() // 這裏觸發了 $digest循環 // }, 2000) } $scope.getMessage() }])
注意:code
但須要延時的時候, 儘量的使用
$timeout
, 這樣, 就不用人爲的去調用$apply()
了。
在調用$apply()
的時候, 應該老是要傳入函數參數, 由於當爲$apply()
傳入函數的時候, 這個函數在調用的時候是包含在try..catch
中, 而且任何發生的異常都可以被$exceptionHandler
服務所接收。htm
$digest
循環要執行多少次呢$digest
循環並不僅是運行一次。在當前循環結束後, 它會再次啓動來檢查是否有數據發生變化, 這被叫作 髒檢查
。$digest
循環會一直保持循環直到再也沒有數據模型發生改變, 或者達到最大的循環次數(10次)。事件
注意:
$digest
至少會循環兩次即便監聽函數沒有更改任何數據模型。它會多運行一次以確保沒有數據發生變化。ip
若是 AngularJS
不能檢測到你的更改, 那麼就必須人爲調用 $apply()
。get