L'erreur ExpressionChangedAfterItHasBeenCheckedError expliquée

Expliquez-moi pourquoi je continue à obtenir cette erreur : `ExpressionChangedAfterItHasBeenCheckedError : L'expression a été modifiée après avoir été vérifiée.

Évidemment, je ne l'obtiens qu'en mode dev, cela ne se produit pas sur ma construction de production, mais c'est très ennuyeux et je ne comprends tout simplement pas les avantages d'avoir une erreur dans mon environnement dev qui n'apparaîtra pas sur prod - probablement à cause de mon manque de compréhension.

En général, la solution est assez simple, il suffit d'envelopper le code qui provoque l'erreur dans un setTimeout comme ceci :

setTimeout(()=> {
    this.isLoading = true;
}, 0);

Ou forcez la détection des changements avec un constructeur comme celui-ci : constructeur(private cd : ChangeDetectorRef) {} :

this.isLoading = true;
this.cd.detectChanges();

Mais pourquoi est-ce que je tombe constamment sur cette erreur ? Je veux la comprendre afin d'éviter ces corrections improvisées à l'avenir.

J'ai eu un problème similaire. En consultant la [documentation sur les crochets de cycle de vie] (https://angular.io/guide/lifecycle-hooks), j'ai remplacé ngAfterViewInit par ngAfterContentInit et ça a marché.

Commentaires (3)

Cette erreur indique un réel problème dans votre application, il est donc logique de lancer une exception.

En devMode la détection de changement ajoute un tour supplémentaire après chaque exécution régulière de détection de changement pour vérifier si le modèle a changé.

Si le modèle a changé entre le tour régulier et le tour supplémentaire de détection de changement, cela indique que soit

  • la détection de changement elle-même a provoqué un changement
  • Une méthode ou un getter renvoie une valeur différente à chaque fois qu'il est appelé.

ce qui est mauvais dans les deux cas, car on ne sait pas comment procéder, le modèle risquant de ne jamais se stabiliser.

Si Angular exécute la détection des changements jusqu'à ce que le modèle se stabilise, cela pourrait fonctionner éternellement. Si Angular n'exécute pas la détection des changements, la vue risque de ne pas refléter l'état actuel du modèle.

Voir aussi https://stackoverflow.com/questions/34868810/what-is-difference-between-production-and-development-mode-in-angular2/34868896#34868896

Commentaires (6)

Mise à jour

Je recommande vivement de commencer par [la réponse personnelle du PO] (https://stackoverflow.com/a/48216423/777285) : réfléchissez bien à ce qui peut être fait dans le constructeur par rapport à ce qui devrait être fait dans ngOnChanges().

Original

C'est plus un aparté qu'une réponse, mais cela pourrait aider quelqu'un. Je suis tombé sur ce problème en essayant de faire en sorte que la présence d'un bouton dépende de l'état du formulaire :

Yo

Pour autant que je sache, cette syntaxe conduit à ce que le bouton soit ajouté et retiré du DOM en fonction de la condition. Ce qui conduit à l'erreur ExpressionChangedAfterItHasBeenCheckedError.

La solution dans mon cas (bien que je ne prétende pas saisir toutes les implications de la différence), a été d'utiliser display : none à la place :

Yo
Commentaires (5)