Vennligst forklar meg hvorfor jeg stadig får denne feilen: `ExpressionChangedAfterItHasBeenCheckedError: Uttrykket har endret seg etter at det ble sjekket".
Åpenbart, jeg får det bare i dev-modus, det skjer ikke på min produksjon bygge, men det er veldig irriterende, og jeg rett og slett ikke forstår fordelene med å ha en feil i min dev miljø som ikke vil dukke opp på prod - sannsynligvis på grunn av min manglende forståelse.
Vanligvis er løsningen enkel nok, jeg pakker bare inn koden som forårsaker feilen i en setTimeout som dette:
setTimeout(()=> {
this.isLoading = true;
}, 0);
Eller tvinge frem endringer med en konstruktør som denne: constructor(private cd: ChangeDetectorRef) {}
:
this.isLoading = true;
this.cd.detectChanges();
Men hvorfor støter jeg stadig på denne feilen? Jeg ønsker å forstå det, slik at jeg kan unngå disse hacky fixes i fremtiden.
Jeg hadde et lignende problem. Ved å se på lifecycle hooks documentation, endret jeg ngAfterViewInit
til ngAfterContentInit
og det fungerte.
Denne feilen indikerer et reelt problem i applikasjonen, og det er derfor fornuftig å kaste et unntak.
I devMode
legger endringsdeteksjon til en ekstra runde etter hver vanlige endringsdeteksjonskjøring for å sjekke om modellen er endret.
Hvis modellen har endret seg mellom den vanlige og den ekstra endringsdeteksjonskjøringen, indikerer dette at enten
begge deler er dårlig, fordi det ikke er klart hvordan man skal gå videre fordi modellen kanskje aldri vil stabilisere seg.
Hvis Angular kjører endringsdeteksjonen til modellen stabiliserer seg, kan den kjøre i all evighet. Hvis Angular ikke kjører endringsregistrering, kan det hende at visningen ikke gjenspeiler modellens nåværende tilstand.
Oppdatering
Jeg anbefaler på det sterkeste å starte med OP's selvsvar først: tenk ordentlig gjennom hva som kan gjøres i constructor
vs hva som bør gjøres i ngOnChanges()
.
**Original
Dette er mer en sidebemerkning enn et svar, men det kan kanskje hjelpe noen. Jeg snublet over dette problemet da jeg prøvde å gjøre tilstedeværelsen av en knapp avhengig av skjemaets tilstand:
<button *ngIf="form.pristine">Yo</button>
Så vidt jeg vet, fører denne syntaksen til at knappen legges til og fjernes fra DOM basert på tilstanden. Noe som igjen fører til ExpressionChangedAfterItHasBeenCheckedError
.
Løsningen i mitt tilfelle (selv om jeg ikke hevder å forstå alle implikasjonene av forskjellen), var å bruke display: none
i stedet:
<button [style.display]="form.pristine ? 'inline' : 'none'">Yo</button>