ExpressionChangedAfterItHasBeenCheckedError in Angular - Kas, kāpēc un kā to labot?

ExpressionChangedAfterItHasBeenCheckedError bez šaubām ir mana mīļākā kļūda leņķiskajās lietojumprogrammās.

Es daudz saskāros ar šo kļūdu, kad pirmo reizi sāku strādāt ar Angular. Saskaņā ar GitHub teikto, tāpat kā daudzi citi.

Kad tiks nomesta ExpressionChangedAfterItHasBeenCheckedError?

Izplatītākie iemesli ir:

  1. Jūs izpildāt kodu AfterViewInit, kas bieži notiek, strādājot ar ViewChild, jo tas nav noteikts, līdz tiek izsaukts AfterViewInit.
  2. Jūs tieši manipulējat ar DOM (piemēram, izmantojot jQuery). Leņķis ne vienmēr var noteikt šīs izmaiņas un pareizi reaģēt.
  3. Tas var notikt arī sacensību apstākļu dēļ, kad jūs izsaucat funkcijas HTML HTML veidnē.

Kas ir ExpressionChangedAfterItHasBeenCheckedError, kurš mēģina mani brīdināt?

ExpressionChangedAfterItHasBeenCheckedError tiek izmests, kad jūsu HTML izteiksme ir mainījusies pēc tam, kad Angular to ir pārbaudījis (tā ir ļoti izteiksmīga kļūda).

Šī kļūda tiek izmesta tikai izstrādes režīmā un pamatota iemesla dēļ; tā bieži ir pazīme, ka jums ir jāpārskata savs kods, jo Leņķis brīdina, ka, ieslēdzot ražošanas režīmu, šīs izteiksmes izmaiņas netiks veiktas!

Viens no iemesliem, kāpēc ražošanas režīms ir ātrāks nekā izstrādes režīms, ir tas, ka leņķis izlaiž dažas pārbaudes (piemēram, izmaiņu noteikšana pēc AfterViewInit), kas tiek veiktas izstrādes režīmā. Tas nozīmē, ka kods, kas darbojas labi izstrādāšanas režīmā, nedarbosies ražošanas režīmā.

Šis ir piemērs, kas labi darbotos izstrādāšanas režīmā, bet ne ražošanas režīmā:

Kā labot ExpressionChangedAfterItHasBeenCheckedError

Labot vienu

Lai ātri izlabotu kļūdu, bieži tiek izmantoti setTimeout vai ChangeDetectorRef.

Pēdējais ir labāks, tāpat kā ar ChangeDetectorRef, tiek pārbaudīts komponenta skats un tā bērni. No otras puses, setTimeout liks leņķim pārbaudīt visu lietojumprogrammu izmaiņām, kas ir daudz dārgāk.

Fiksējiet divus

Dažreiz kļūdu ir vēl vieglāk novērst - vienkārši pārvietojiet kodu uz OnInit.

Ja vien jums nav jāpaļaujas uz ViewChild vai ja kādam kodam vajadzētu darboties tikai pēc tam, kad leņķis ir pilnībā inicializējis komponenta skatu, pāreja uz OnInit atrisinās jūsu problēmu.

Tas ir tāpēc, ka leņķiskais pēc OnInit veiks izmaiņu noteikšanu gan ražošanas, gan izstrādes režīmā.

Fiksējiet trīs

Vai jums nepatīk leņķiskā maģija un kā tā uztver izmaiņas? Vienkārši atspējojiet automātisko izmaiņu noteikšanu savā komponentā un pasakiet Leņķim pats, kad tam vajadzētu atklāt izmaiņas.

ChangeDetectionStrategy var norādīt komponentu dekoratorā uz OnPush. Tagad leņķis tikai automātiski noteiks ievades izmaiņas, un pārējais ir atkarīgs no jums.

Lai gan, ieslēdzot TheOnPush stratēģiju, ir iesaistīts mazāk burvju, jūs arī iegūstat labāku sniegumu, jo Leņķa darbam ir mazāk darba. Tas var būt noderīgi lielu un sarežģītu komponentu optimizēšanai.

No otras puses, jums jāpārliecinās, ka ļāva leņķim uzņemt izmaiņas. Ja jūs to nedarīsit, parasti redzēsit UI kļūdas (piemēram, modulis nepazūd).

Tāpēc nelietojiet to pārāk dedzīgi, rūpīgi nepārbaudot savu komponentu.

Secinājums

Tagad jums vajadzētu būt spējīgam saprast, kad un kāpēc notiek draņķīgais ExpressionChangedAfterItHasBeenCheckedError.

Kā redzat, ir vairākas iespējas, kā novērst šo kļūdu. Vienkārši pārliecinieties, ka jūs faktiski atrisināt patieso pamatā esošo problēmu, nevis strādājat ap to.