Angularは、変更検知が完了した後に式の値が変更された場合に、ExpressionChangedAfterItHasBeenCheckedError
をスローします。Angularはこのエラーを開発モードでのみスローします。
開発モードでは、Angularは各変更検知の実行後に追加のチェックを実行して、バインディングが変更されていないことを確認します。これにより、ビューが不整合な状態で残されるエラーがキャッチされます。たとえば、メソッドまたはゲッターが呼び出されるたびに異なる値を返す場合、または子コンポーネントが親の値を変更する場合に発生する可能性があります。いずれかの場合も、これは変更検知が安定していないことを示しています。Angularは、データが常にビューに正しく反映され、UI動作が不安定になる可能性や無限ループを防ぐために、エラーをスローします。
このエラーは、テンプレート式を追加した場合、またはngAfterViewInit
やngOnChanges
などのライフサイクルフックの実装を開始した場合に、一般的に発生します。また、ローディングステータスや非同期操作を扱う場合、または子コンポーネントが親バインディングを変更する場合にも一般的です。
エラーのデバッグ
CLIによって生成されたソースマップは、デバッグ時に非常に役立ちます。呼び出しスタックを上って、エラーに表示されている値が変更されたテンプレート式を見つけるまでナビゲートします。
変更検知が実行された後にテンプレートのバインディングに変更がないことを確認します。これは多くの場合、ユースケースに適切なコンポーネントライフサイクルフックを使用するようにリファクタリングすることを意味します。問題がngAfterViewInit
内にある場合、初期値を設定するためにコンストラクターまたはngOnInit
を使用するか、他の値バインディングのためにngAfterContentInit
を使用することをお勧めします。
ビューでメソッドにバインディングしている場合、呼び出しがテンプレート内の他のバインディングを更新しないことを確認してください。
どのソリューションが自分に適しているかについては、'「ExpressionChangedAfterItHasBeenCheckedError」エラーに関するすべて'と、これがなぜ役立つのかについては、'Angularデバッグ「Expression has changed after it was checked」: 簡単な説明(と修正)'をご覧ください。