ExpressionChangedAfterItHasBeenCheckedError in nurga all - mida, miks ja kuidas seda parandada?

ExpressionChangedAfterItHasBeenCheckedError on kahtlemata minu lemmikviga nurgarakendustes.

Ma leidsin selle veaga palju, kui hakkasin esimest korda Angulariga koostööd tegema. GitHubi sõnul teevad seda paljud teisedki.

Millal ExpressionChangedAfterItHasBeenCheckedError visatakse?

Kõige tavalisemad põhjused on:

  1. Käivitate koodi AfterViewInit, mis juhtub sageli ViewChildiga töötamisel, kuna see pole defineeritud, kuni AfterViewInit kutsutakse.
  2. Te manipuleerite otse DOM-iga (nt kasutades jQuery). Nurk ei suuda neid muutusi alati tuvastada ja korralikult reageerida.
  3. See võib juhtuda ka võistlustingimuste tõttu, kui kutsute HTML-malli funktsioone.

Mis on ExpressionChangedPärastKasBeenCheckedError proovib mind hoiatada?

ExpressionChangedAfterItHasBeenCheckedError visatakse siis, kui teie HTML-i avaldis on muutunud pärast seda, kui Angular on selle kontrollinud (see on väga väljendusrikas viga).

See viga visatakse ainult arendusrežiimis ja mõjuval põhjusel; see on sageli märk sellest, et peaksite oma koodi uuesti muutma, kuna Nurk hoiatab teid, et selle muutust teie avaldis ei võeta tootmisrežiimi lubamisel!

Üks põhjus, miks tootmisrežiim on kiirem kui arendusrežiim, on see, et nurk jätab vahele mõned kontrollrežiimid (nt muudatuste tuvastamine pärast AfterViewInit), mis tehakse arendusrežiimis. See tähendab, et arendusrežiimis hästi töötav kood ei tööta tootmisrežiimis.

Siin on näide, mis toimiks hästi arendusrežiimis, kuid mitte tootmisrežiimis:

Kuidas parandada ExpressionChangedAfterItHasBeenCheckedError

Paranda üks

Kiirparandusena kasutatakse vea kadumiseks sageli setTimeout või ChangeDetectorRef.

Viimane on parem, nagu ka ChangeDetectorRef puhul, komponendi vaadet ja selle lapsi kontrollitakse. Teisest küljest paneb setTimeout Angular kontrollima kogu rakenduse muudatusi, mis on palju kallim.

Parandage kaks

Mõnikord on seda viga veelgi lihtsam parandada - lihtsalt teisaldage oma kood OnInit.

Kui te ei pea lootma ViewChildile või kui mõni kood peaks käivituma alles pärast seda, kui Angular on komponendi vaate täielikult initsialiseerinud, lahendab OnInit'i kolimine teie probleemi.

Selle põhjuseks on asjaolu, et nurk teostab muudatuste tuvastamise pärast OnInit nii tootmise kui ka arendusrežiimis.

Parandage kolm

Kas teile ei meeldi nurgavõlu ja kuidas see muutusi tuvastab? Lihtsalt keerake oma komponendis automaatne muudatuste tuvastamine ja öelge endale Nurga all, millal see peaks muudatusi tuvastama.

ChangeDetectionStrategy saab määrata komponentide sisekujundajana OnPushile. Nüüd tuvastab nurk sisendmuudatused ainult automaatselt ja ülejäänu on teie otsustada.

Ehkki strateegia OnLush lubamisega on vähem maagiat, saate ka parema jõudluse, kuna nurga all on vähem tööd. See võib olla kasulik suurte ja keerukate komponentide optimeerimiseks.

Teisest küljest peate kindlasti veenduma, et lubate nurgal muudatusi üles võtta. Kui te seda ei tee, näete tavaliselt kasutajaliidese vigu (nt modaal ei kao).

Seega, ärge rakendage seda liiga innukalt, ilma et oleks oma komponenti põhjalikult kontrollinud.

Järeldus

Nüüd peaksite saama aru, millal ja miks ilmneb kurikuulus ExpressionChangedAfterItHasBeenCheckedError.

Nagu näete, on selle vea lahendamiseks mitu viisi. Lihtsalt veenduge, et lahendate selle asemel selle tegeliku probleemi.