J'ai un bug dans mon angular qui a finalement été résolu en encapsulant mon code dans
this.zone.run(() => {/* my code here */});
comme indiqué par this réponse.
Ma compréhension précédente de zone
était que angular ne peut pas détecter les modifications apportées par async callbacks
des bibliothèques tierces car "elles ne sont pas dans angular's zone
". Si je clique sur un button
, l'événement qui se déclenche n'est pas un événement natif click
du navigateur mais un événement personnalisé (corrigé) click
créé par = angular dont handler
s'exécute dans le zone
donc angular est conscient des modifications apportées par son gestionnaire de rappel).
Mais je ne pouvais pas comprendre en exécutant router.navigate()
dans un rappel tiers créer ce problème (comme indiqué par this github issue). Router
n'est pas un service
de angular lui-même? Pourquoi n'informe-t-il pas automatiquement le zone
d'angular lorsqu'il est appelé par un tiers callback
?
J'ai eu ce problème en utilisant router.navigate
Dans le réducteur d'état de NGXS.
Ma question est:
Quelqu'un peut-il expliquer quand dois-je exactement envelopper mon code dans NgZone
?
Déboguer pendant des heures et réaliser que mon code est hors du contexte zone
est fastidieux.
ngZone.run()
est particulièrement utile lors des tests unitaires de votre routage.
it('should redirect if condition true, fakeAsync(() => {
router.navigate(['']);
fixture.ngZone.run(() => {
component.redirectIfConditionTrue();
});
tick();
expect(location.path()).toBe('/AgentLeadsManager');
}));
ngZone.runOutsideAngular () - cela exécute le code en dehors de la zone angular.
Angular utilise lui-même ngZone sous le capot pour détecter les changements
Donc, si nous sommes sortis de la zone angular, alors pour revenir, nous utilisons ngZone.run()
Zone.js est un contexte d'exécution pour le suivi et l'interception d'opérations asynchrones comme: les événements DOM (
click
,keydown
,keyup
,etc
),setTimeout
,setInterval
.XMLHttpRequest
s
NgZone n'est qu'un wrapper angular autour de l'API de Zone.js
).
L'équipe Angular Angular a décidé qu'elle avait besoin de l'abstraction pour un contexte d'exécution tout en travaillant sur Angular afin qu'ils aient construit Zone.js et un wrapper (informellement - modèle d'adaptateur) autour de en angulaire.
Donc, fondamentalement, pour répondre à votre question: lorsque vous traitez avec n'importe quel type de bibliothèque tierce qui n'est pas liée au contexte d'exécution d'Angular dans Zone.js (sauf si vous avez décidé que vous n'avez pas besoin du contexte d'exécution et que vous pouvez travailler sans = il utilise NoopNgZone
)