ExpressionChangedAfterItHasBeenCheckedError in Angular - Hvad, hvorfor og hvordan fikser man det?

ExpressionChangedAfterItHasBeenCheckedError er uden tvivl min yndlingsfejl i vinkel applikationer.

Jeg stødte meget på denne fejl, da jeg først begyndte at arbejde med Angular. Ifølge GitHub gør det også mange andre.

Hvornår udtrykkelse vil blive ændret efter at det er gået, kontrolleret, error kastes?

De mest almindelige årsager er:

  1. Du udfører kode i AfterViewInit, som ofte sker, når du arbejder med ViewChild, da den er udefineret, indtil AfterViewInit kaldes.
  2. Du manipulerer DOM direkte (f.eks. Ved hjælp af jQuery). Vinkelformet kan ikke altid registrere disse ændringer og reagere korrekt.
  3. Det kan også ske på grund af løbsbetingelser, når du ringer til funktioner i din HTML-skabelon.

Hvad er udtryk forankretEfterHet ereenhederTjeketError forsøger at advare mig om?

ExpressionChangedAfterItHasBeenCheckedError kastes, når et udtryk i din HTML er ændret, når Angular har kontrolleret det (det er en meget udtryksfejl).

Denne fejl kastes kun i udviklingsfunktion og med god grund; Det er ofte et tegn på, at du skal refaktorere din kode, da Angular advarer dig om, at denne ændring i dit udtryk ikke bliver afhentet, når du aktiverer produktionstilstand!

En af grundene til, at produktionstilstand er hurtigere end udviklingsfunktion, er, at Vinkelformat springer nogle kontroller over (f.eks. Ændre detektion efter AfterViewInit), der udføres i udviklingsfunktion. Det betyder, at kode, der fungerer fint i udviklingsfunktion, ikke fungerer i produktionstilstand.

Her er et eksempel, der ville fungere fint i udviklingsfunktion, men ikke i produktionstilstand:

Sådan rettes udtrykket forandret efter det har været beancheckedError

Fix en

Som en hurtig løsning bruges ofte setTimeout eller ChangeDetectorRef til at få fejlen til at forsvinde.

Det sidstnævnte er bedre, som med ChangeDetectorRef komponentvisningen og dens børn kontrolleres. På den anden side vil setTimeout få Angular til at kontrollere hele applikationen for ændringer, hvilket er langt dyrere.

Fix to

Nogle gange er fejlen endnu lettere at rette - bare flyt din kode til OnInit.

Medmindre du er nødt til at stole på ViewChild, eller hvis en eller anden kode kun skal køres, når Angular fuldstændigt har initialiseret en komponentvisning, vil flytning til OnInit løse dit problem.

Dette skyldes, at Angular udfører ændringsdetektering efter OnInit i både produktions- og udviklingsfunktion.

Fix tre

Kan du ikke lide kantet magi, og hvordan det registrerer ændringer? Deaktiver bare automatisk ændringsdetektion i din komponent og fortæl Angular selv, hvornår den skal registrere ændringer.

ChangeDetectionStrategy kan specificeres i en komponentdekoratør til OnPush. Nu registrerer Angular kun inputændringer automatisk, og resten er op til dig.

Mens der er mindre magi involveret ved at aktivere TheOnPush-strategien, får du også forbedret ydelse, da der er mindre arbejde for Angular at gøre. Dette kan være nyttigt til at optimere store og komplekse komponenter.

På den anden side skal du sørge for, at du lader Vinkelformular hente ændringer. Hvis du ikke gør det, vil du normalt se UI-fejl (f.eks. En modal, der ikke forsvinder).

Så anvend ikke dette ivrigt uden at kontrollere din komponent grundigt.

Konklusion

Du skal nu være i stand til at forstå, hvornår og hvorfor den berygtede udtryk ChangedAfterItHasBeenCheckedError opstår.

Som du kan se, er der flere måder at håndtere denne fejl på. Bare sørg for, at du rent faktisk løser det reelle underliggende problem i stedet for at arbejde omkring det.