$ apply vs $ digest nei test delle direttive


98

Se ho una direttiva che risponde allo stato di un particolare attributo nell'ambito e desidero modificare quell'attributo nel mio test e verificare che risponda correttamente, qual è il modo migliore per eseguire tale modifica?

Ho visto entrambi questi modelli:

scope.$apply(function() {
    scope.myAttribute = true;
});

e

scope.myAttribute = true;
scope.$digest();

Qual è la differenza tra loro e quale è meglio e perché?

Risposte:


206

scope.$digest()licenzierà gli osservatori sull'ambito corrente e anche su tutti i suoi figli. scope.$applyvaluterà la funzione passata ed eseguirà $rootScope.$digest().

Il primo è più veloce, poiché deve valutare gli osservatori per l'ambito corrente e i suoi figli. Il secondo è più lento, poiché deve valutare gli osservatori $rootScopee tutti i suoi ambiti figlio.

Quando si verifica un errore in uno degli watcher e che utilizzi scope.$digest, non viene gestito tramite il $exceptionHandlerservizio, quindi devi gestire tu stesso l'eccezione. scope.$applyutilizza un try-catchblocco internamente e passa tutte le eccezioni a $exceptionHandler.


1
Verranno $digestchiamati anche i figli dell'ambito?
pilau

15
Questo può essere fuorviante. $digestnon solo licenzia gli osservatori sull'ambito corrente, ma anche su tutti i suoi figli.
tasseKATT

@tasseKATT, penso di aver catturato ciò che suggerisce il tuo commento.
attivo il

12

Poiché la documentazione stessa menziona $ digest, il ciclo viene eseguito ogni volta che lo fai $scope.$apply. Come da guida per sviluppatori sull'ambito

Dopo aver valutato l'espressione, il metodo $ apply esegue un $ digest. Nella fase $ digest, l'ambito esamina tutte le espressioni $ watch e le confronta con il valore precedente.

E come da documentazione dell'API Scope

Di solito non chiami $ digest () direttamente nei controller o nelle direttive. Invece una chiamata a $ apply () (tipicamente dall'interno di una direttiva) forzerà un $ digest ().

Quindi non dovresti chiamare esplicitamente $digest, la chiamata del $applymetodo innescherebbe un ciclo digest.


8
questo non è vero poiché digest è sufficiente per la maggior parte dei casi in cui è necessario valutare solo l'ambito corrente e i relativi figli. è vero che $ scope. $ apply chiama $ digest internamente ma è molto importante ricordare che finirà per chiamare $ rootScope. $ digest () e quindi molto pesante
Srivathsa Harish Venkataramana
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.