ExpressionChangedAfterItHasBeenCheckedError in Angular - Co, dlaczego i jak go naprawić?

ExpressionChangedAfterItHasBeenCheckedError to bez wątpienia mój ulubiony błąd w aplikacjach Angular.

Często napotkałem ten błąd, kiedy zaczynałem pracę z Angularem. Według GitHub, podobnie jak wiele innych.

Kiedy zostanie wyrzucony ExpressionChangedAfterItHasBeenCheckedError?

Najczęstsze przyczyny to:

  1. Wykonujesz kod w AfterViewInit, co często zdarza się podczas pracy z ViewChild, ponieważ jest niezdefiniowany do momentu wywołania AfterViewInit.
  2. Manipulujesz DOM bezpośrednio (np. Za pomocą jQuery). Angular nie zawsze może wykryć te zmiany i odpowiednio zareagować.
  3. Może się to również zdarzyć z powodu warunków wyścigu, gdy wywołujesz funkcje wewnątrz szablonu HTML.

Co to jest ExpressionChangedAfterItHasBeenCheckedError Próbuje mnie ostrzec?

ExpressionChangedAfterItHasBeenCheckedError jest generowany, gdy wyrażenie w kodzie HTML uległo zmianie po sprawdzeniu go przez Angular (jest to bardzo ekspresyjny błąd).

Ten błąd jest zgłaszany tylko w trybie programowania i nie bez powodu; często jest to znak, że powinieneś zmienić kod, ponieważ Angular ostrzega cię, że ta zmiana twojego wyrażenia nie zostanie zauważona po włączeniu trybu produkcyjnego!

Jednym z powodów, dla których tryb produkcji jest szybszy niż tryb programowania, jest to, że Angular pomija niektóre kontrole (np. Wykrywanie zmian po AfterViewInit), które są wykonywane w trybie programowania. Oznacza to, że kod, który będzie działał poprawnie w trybie programowania, nie będzie działał w trybie produkcyjnym.

Oto przykład, który działałby dobrze w trybie programowania, ale nie w trybie produkcyjnym:

Jak naprawić ExpressionChangedAfterItHasBeenCheckedError

Napraw jeden

Szybką poprawką jest często użycie setTimeout lub ChangeDetectorRef, aby błąd zniknął.

To drugie jest lepsze, ponieważ w przypadku ChangeDetectorRef widok komponentu i jego elementy potomne są sprawdzane. Z drugiej strony setTimeout spowoduje, że Angular sprawdzi całą aplikację pod kątem zmian, co jest znacznie droższe.

Napraw dwa

Czasami błąd jest nawet łatwiejszy do naprawienia - wystarczy przenieść kod do OnInit.

O ile nie musisz polegać na ViewChild lub jeśli jakiś kod powinien zostać uruchomiony tylko po pełnym zainicjowaniu widoku komponentu przez Angular, przejście na OnInit rozwiąże problem.

Wynika to z faktu, że Angular wykona wykrywanie zmian po OnInit zarówno w trybie produkcyjnym, jak i programistycznym.

Napraw trzy

Nie lubisz magii kątowej i tego, jak wykrywa zmiany? Po prostu wyłącz automatyczne wykrywanie zmian w swoim komponencie i powiedz Angularowi, kiedy powinien wykryć zmiany.

ChangeDetectionStrategy można określić w dekoratorze komponentów do OnPush. Teraz Angular wykrywa tylko zmiany danych wejściowych automatycznie, a reszta zależy od Ciebie.

Włączenie strategii OnPush wymaga mniejszej magii, ale zwiększasz wydajność, ponieważ Angular ma mniej pracy. Może to być przydatne do optymalizacji dużych i złożonych komponentów.

Z drugiej strony musisz upewnić się, że pozwalasz Angularowi odbierać zmiany. Jeśli tego nie zrobisz, zwykle zobaczysz błędy interfejsu użytkownika (np. Modal nie znika).

Nie stosuj tego zbyt wcześnie, nie sprawdzając dokładnie swojego komponentu.

Wniosek

Powinieneś teraz być w stanie zrozumieć, kiedy i dlaczego pojawia się niesławny ExpressionChangedAfterItHasBeenCheckedError.

Jak widać, istnieje wiele sposobów radzenia sobie z tym błędem. Upewnij się, że faktycznie rozwiązujesz prawdziwy problem, zamiast go obejść.