$ apply vs $ digest dans les tests de directives


98

Si j'ai une directive qui répond au statut d'un attribut particulier sur la portée et que je souhaite modifier cet attribut dans mon test et vérifier qu'il répond correctement, quelle est la meilleure façon de faire ce changement?

J'ai vu ces deux modèles:

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

et

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

Quelle est la différence entre eux, quel est le meilleur et pourquoi?

Réponses:


206

scope.$digest()lancera des observateurs sur la lunette actuelle, et sur tous ses enfants aussi. scope.$applyévaluera la fonction passée et exécutera $rootScope.$digest().

Le premier est plus rapide, car il doit évaluer les observateurs pour la portée actuelle et ses enfants. Le second est plus lent, car il doit évaluer les observateurs $rootScopeet toutes ses portées enfants.

Lorsqu'une erreur se produit dans l'un des observateurs et que vous utilisez scope.$digest, elle n'est pas gérée via le $exceptionHandlerservice, vous devez donc gérer l'exception vous-même. scope.$applyutilise un try-catchbloc en interne et transmet toutes les exceptions à $exceptionHandler.


1
Sera $digestégalement appelé les enfants du télescope?
pilau

15
Cela peut être trompeur. $digestne tire pas seulement les observateurs sur la portée actuelle, mais aussi sur tous ses enfants.
tasseKATT

@tasseKATT, je pense avoir capturé ce que votre commentaire suggère.
activé le

12

Comme la documentation elle-même le mentionne, $ digest cycle est exécuté à chaque fois que vous le faites $scope.$apply. Selon le guide du développeur sur la portée

Après avoir évalué l'expression, la méthode $ apply effectue un $ digest. Dans la phase $ digest, l'étendue examine toutes les expressions $ watch et les compare avec la valeur précédente.

Et selon la documentation de l' API Scope

Habituellement, vous n'appelez pas $ digest () directement dans les contrôleurs ou dans les directives. Au lieu de cela, un appel à $ apply () (généralement à partir d'une directive) forcera un $ digest ().

Vous ne devez donc pas appeler explicitement $digest, votre $applyméthode d' appel déclencherait un cycle de résumé.


8
ce n'est pas vrai car digest est suffisant pour la plupart des cas où seuls la portée actuelle et ses enfants doivent être évalués. il est vrai que $ scope. $ apply appelle $ digest en interne mais il est très important de se rappeler qu'il finira par appeler $ rootScope. $ digest () et donc très lourd
Srivathsa Harish Venkataramana
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.