ExpressionChangedAfterItHasBeenCheckedError Forklart

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.

Kommentarer (3)

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

  • endringsregistreringen i seg selv har forårsaket en endring
  • en metode eller getter returnerer en annen verdi hver gang den kalles.

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.

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

Kommentarer (6)

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:

Yo

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:

Yo
Kommentarer (5)