オフィス狛 技術部のKoma(Twitterアカウントの中の人&CEO)です。
私の担当がいつの間にかAngular専任になっていますが・・・・今回もやっぱりAngularネタです。
Angularで、NgRxなどでAPIから値を取得した場合、そのままView(template・html)側にデータを流し込んであげれば、取得したデータは問題なく表示されます。
ところが、component(TypeScript)側で取得したデータをstore.selectで取得すると、View(template・html)側に表示データが反映されない場合があります。
うーん、言葉だけで説明するのが難しい。
この辺はいつかNgRxの使い方とかで詳しく説明したいですが、前者の場合、ストリーム(川の流れ)は繋ぎっぱなしですが、
後者は、一度ストリーム(川の流れ)から、データ取っているので、流れが止まっている、という事ですね。
強制的に画面に反映させる為には、「changeDetectorRef の detectChanges() 」メソッドを使います。
では、ここで使い方の例を一つ。
import { Component, ChangeDetectorRef, OnInit } from '@angular/core';
// (中略)
export class HogeKomaComponent implements OnInit {
// (中略)
constructor(
public store: Store,
private changeDetectorRef: ChangeDetectorRef
) {}
ngOnInit() {
this.hogeKomaSubscription.push(
this.store
.select(fromHoge.getKomaList)
.pipe(skip(1))
.subscribe(result => {
//
// ここで取得したデータを編集し、Template側の変数へ再設定(これだけだと、画面は更新されない)
//
// 画面の表示を更新する(これを実施する事で画面が更新される)
this.changeDetectorRef.detectChanges();
}));
// データ取得
this.store.dispatch(new KomaListActions.GetKomaList());
}
で、ここからが本題なのですが、「detectChanges()」を使っていると、以下のようなエラーが発生する事があります。
common.96cfb6ba445916612966.js:1 ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges
at pm (main.35927d7a5d9b4fa62e08.js:1)
at Object.m_ [as updateDirectives] (main.35927d7a5d9b4fa62e08.js:1)
at jv (main.35927d7a5d9b4fa62e08.js:1)
at D_ (main.35927d7a5d9b4fa62e08.js:1)
at Object.i_ [as checkAndUpdateView] (main.35927d7a5d9b4fa62e08.js:1)
at n.detectChanges (main.35927d7a5d9b4fa62e08.js:1)
at e._next (10.ab643854ddb1ed074304.js:1)
at e.__tryOrUnsub (main.35927d7a5d9b4fa62e08.js:1)
at e.next (main.35927d7a5d9b4fa62e08.js:1)
at e._next (main.35927d7a5d9b4fa62e08.js:1)
エラーメッセージは、
ViewDestroyedError: Attempt to use a destroyed view: detectChanges
という事ですが、要は、「画面表示を行おうとしたけど、もう対象のViewが存在しない」という事ですね。
こういう場合は、
if (!this.changeDetectorRef['destroyed']) {
this.changeDetectorRef.detectChanges();
}
上記のように、既にViewが破棄されていないか確認する事で回避出来ます。
今回も内容の割には長くなってしまいました・・・・
(エラーメッセージと対応内容書けば、ある意味終了なんですけどね。)
こんな内容でも、誰かの役に立つ事を願って・・・・
では、より良いAngularライフを!
Angular
