Bitte erklären Sie mir, warum ich immer wieder diesen Fehler erhalte: `ExpressionChangedAfterItHasBeenCheckedError: Ausdruck hat sich geändert, nachdem er geprüft wurde".
Offensichtlich bekomme ich es nur im Dev-Modus, es passiert nicht auf meinem Produktions-Build, aber es ist sehr ärgerlich, und ich verstehe einfach nicht die Vorteile eines Fehlers in meiner Dev-Umgebung, die nicht auf Prod auftauchen wird - wahrscheinlich wegen meines Mangels an Verständnis.
Normalerweise ist die Lösung einfach genug, ich verpacke einfach den fehlerverursachenden Code in ein setTimeout wie dieses:
setTimeout(()=> {
this.isLoading = true;
}, 0);
Oder erzwingen Sie die Erkennung von Änderungen mit einem Konstruktor wie diesem: constructor(private cd: ChangeDetectorRef) {}
:
this.isLoading = true;
this.cd.detectChanges();
Aber warum stoße ich ständig auf diesen Fehler? Ich möchte es verstehen, damit ich diese umständlichen Korrekturen in Zukunft vermeiden kann.
Ich hatte ein ähnliches Problem. Nach einem Blick in die [lifecycle hooks documentation] (https://angular.io/guide/lifecycle-hooks) habe ich ngAfterViewInit
in ngAfterContentInit
geändert und es hat funktioniert.
Dieser Fehler deutet auf ein echtes Problem in Ihrer Anwendung hin, weshalb es sinnvoll ist, eine Ausnahme zu werfen.
Im devMode
fügt die Änderungserkennung nach jedem regulären Änderungserkennungslauf eine zusätzliche Runde hinzu, um zu prüfen, ob sich das Modell geändert hat.
Wenn sich das Modell zwischen dem regulären und dem zusätzlichen Änderungserkennungslauf geändert hat, bedeutet dies, dass entweder
was beides schlecht ist, weil nicht klar ist, wie es weitergehen soll, weil sich das Modell möglicherweise nie stabilisiert.
Wenn Angular die Änderungserkennung so lange laufen lässt, bis sich das Modell stabilisiert hat, könnte es für immer laufen. Wenn Angular keine Änderungserkennung durchführt, könnte die Ansicht nicht den aktuellen Zustand des Modells widerspiegeln.
Aktualisierung
Ich empfehle dringend, zuerst mit [the OP's self response] (https://stackoverflow.com/a/48216423/777285) zu beginnen: richtig darüber nachzudenken, was im constructor
gegenüber dem, was in ngOnChanges()
getan werden sollte, getan werden kann.
Original
Dies ist mehr eine Randnotiz als eine Antwort, aber vielleicht hilft es jemandem. Ich bin über dieses Problem gestolpert, als ich versucht habe, das Vorhandensein einer Schaltfläche vom Zustand des Formulars abhängig zu machen:
<button *ngIf="form.pristine">Yo</button>
Soweit ich weiß, führt diese Syntax dazu, dass die Schaltfläche je nach Bedingung zum DOM hinzugefügt oder aus ihm entfernt wird. Das wiederum führt zu dem Fehler "ExpressionChangedAfterItHasBeenCheckedError".
Die Lösung in meinem Fall (obwohl ich nicht behaupte, die volle Tragweite des Unterschieds zu verstehen) war, stattdessen display: none
zu verwenden:
<button [style.display]="form.pristine ? 'inline' : 'none'">Yo</button>