2016-03-09 26 views
0

我是一個角度noob,我想了解爲什麼以下觸發器「$ apply已在進行中......」錯誤。

下面是代碼(和它真的幾乎直接從文檔:https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$digest

<!DOCTYPE html> 
<html> 

<head> 
    <script src="js/lib/angular.js"></script> 
    <script> 
    var app = angular.module('app', []); 
    app.controller('MainController', ['$scope', function(scope) { 
     scope.name = 'misko'; 
     scope.counter = 0; 
     //A 
     scope.$watch('name', function(newValue, oldValue) { 
      scope.count++; 
     }); 
     //B 
     scope.$digest(); 
    }]); 
    </script> 
</head> 

<body> 
    <div ng-app='app' ng-controller="MainController"> 
    </div> 
</body> 

</html> 

而且,這裏是小提琴:https://jsfiddle.net/zLny2faq/5/

我得到了在著名的「$在已申請進展「錯誤,但爲什麼呢?

我想知道爲什麼摘要循環觸發,甚至沒有被稱爲?

換句話說,我只是聲明監聽者(@comment A)並通過調用$ digest()(@comment B)來觸發他們。但是,當我明確地調用$ digest()時,它好像被以某種方式快速調用並出錯。這是爲什麼?

請指教。

+0

您的代碼不作很有道理。你爲什麼要調用scope?$ digest()? $ watch已經被觸發,因爲您設置了名稱變量。一般來說,只需要在角框架外調用$ digest/$ apply,例如在單元測試中。 – dz210

+0

@ dz210這段代碼幾乎是直接從文檔中直接得到的,但是不是真正在$ watch之前設置的名稱變量。 – 82Tuskers

回答

1

名稱變量設置手錶是以前的,但所有的手錶獲得的初始化調用一次:

Per Angular Docs

觀察者與範圍註冊之後,聽者FN是 異步調用(通過$ evalAsync)來初始化觀察者。在極少的情況下,這是不受歡迎的,因爲當watchExpression的結果沒有改變時調用監聽器。要在偵聽器fn中檢測此場景 ,可以比較newVal和oldVal。如果 這兩個值是相同的(===),那麼聽者被稱爲 初始化。

^可以照顧via

$scope.$watch('name', function(newValue, oldValue) { 
    if (newValue !== oldValue) { 
    // will only run if the value changes, on initial load the newvalue = oldvalue so it won't run this code. 
    } 
}); 
0

如果你真的需要$調用消化,您可以使用

$timeout(function(){ 
    scope.$digest(); 
}, 0); 

Fiddle