ngOninit で時間のかかる非同期処理を行い、
ブラウザの開発者モードで表示した際に、
コンソールに下記エラーが発生しました。(画面は正常に動いている。)
|
|
何が起こっていたのか
Angular の変更検知のサイクルの一つである、
コンポーネントのライフサイクルフックが終わった後に、(ngOninit など)
非同期処理のデータが流れてきたため、エラーが発生していたと思われます。
でも、Angular にとって、非同期なデータが画面描画後に来ることは普通のことな気がしていて、
よく分からないなと言う感想です。
ただ、今回の状況を振り返ると、
ngAffterViewInit でエラーが起きていました。
ngAffterViewInit は一度しか呼ばれないのが通常な為、
今回のエラーが発生したと思われます。
解決方法は ChangeDetectorRef.detectChanges()
ngAffterViewInit の該当処理の後に、
ChangeDetectorRef.detectChanges()を入れることで、
ブラウザ側のエラーが解消しました。
ChangeDetectorRef について調べた
ChangeDetectorRef.detectChanges()を追加することで、回避しているのですが、
どういうクラスなのか確認していきます。
ChangeDetectorRef には下記メソッドがあります。
- markForCheck
- detach
- detectChanges
- checkNoChanges
- reattach
まず、detach,reattach はそれぞれ変更検知を止める処理と、
動かす処理になります。
そもそも、変更検知って何かを例えると、
人間の感覚器官のようなものだと思います。
その為、detach すると視覚も聴覚も触覚も全てが無くなるが、
意識はあるようなイメージです。怖すぎ笑
checkNoChanges は前回の状態から差異がないことを確認するメソッドです。
差異がある場合、ブラウザの開発者モードでエラーを出力するみたいです。
markForCheck は次回の変更検知の際に、対象のコンポーネントに対して、
変更検知のサイクルを動かしたいときに使います。
変更検知のサイクルを自動ではなく、手動で管理したい際に使うものみたいですね。
変更検知を手動で動かしたい場合は、コンポーネントの設定に、下記を追加することで、
Angular の変更検知を手動で動かせるようになるようです。(デフォルトは自動になります)
|
|