Angular 8 の @ViewChild の新しい静的オプションをどのように使用すればよいですか? 質問する

Angular 8 の @ViewChild の新しい静的オプションをどのように使用すればよいですか? 質問する

新しい Angular 8 ビューの子をどのように構成すればよいですか?

@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;

@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;

static:trueどちらが良いでしょうか? vsはいつ使用すればよいでしょうかstatic:false

ベストアンサー1

ほとんどの場合、 を使用することになります{static: false}。このように設定すると、バインディング解決に依存するクエリ一致 (構造ディレクティブ など*ngIf, etc...) が確実に見つかります。

使用例static: false:

@Component({
  template: `
    <div *ngIf="showMe" #viewMe>Am I here?</div>
    <button (click)="showMe = !showMe"></button>
  ` 
})
export class ExampleComponent {
  @ViewChild('viewMe', { static: false })
  viewMe?: ElementRef<HTMLElement>; 

  showMe = false;
}

これはstatic: falseAngular 9 のデフォルトのフォールバック動作になります。続きを読むここそしてここ

この{ static: true }オプションは、埋め込みビューをオンザフライで作成できるようにするために導入されました。動的にビューを作成し、 にアクセスしたい場合、エラーが発生するためTemplateRefではアクセスできません。static フラグを true に設定すると、ngOnInit でビューが作成されます。ngAfterViewInitExpressionHasChangedAfterChecked

それにもかかわらず:

その他のほとんどの場合、 を使用するのがベストプラクティスです{static: false}

ただし、この{ static: false }オプションは Angular 9 でデフォルトになることに注意してください。つまり、このstatic: trueオプションを使用する場合を除き、静的フラグを設定する必要はなくなります。

Angular CLIng updateコマンドを使用して、現在のコード ベースを自動的にアップグレードできます。

移行ガイドやこれに関する詳しい情報については、以下をご覧ください。ここそしてここ

#静的クエリと動的クエリの違いは何ですか? @ViewChild() および @ContentChild() クエリの静的オプションによって、クエリ結果がいつ利用可能になるかが決まります。

静的クエリ (static: true) では、ビューが作成された後、変更検出が実行される前にクエリが解決されます。ただし、ngIf ブロックや ngFor ブロックの変更など、ビューの変更を反映するように結果が更新されることはありません。

動的クエリ (static: false) では、クエリはそれぞれ @ViewChild() と @ContentChild() の ngAfterViewInit() または ngAfterContentInit() の後に解決されます。結果は、ngIf ブロックや ngFor ブロックの変更など、ビューの変更に応じて更新されます。


を使用する良いユースケースは、テンプレートで定義された要素にバインドするために をstatic: true使用する場合です。次のテンプレートを検討してください。fromEvent

<div [ngStyle]="thumbStyle$ | async" #thumb></div>

その後、サブスクリプションや init フックを使用せずに、この要素のイベントを処理できます (Angular イベント バインディングを使用しない、または使用できない場合)。

@Component({})
export class ThumbComponent {
  @ViewChild('thumb', { static: true })
  thumb?: ElementRef<HTMLElement>;

  readonly thumbStyle$ = defer(() => fromEvent(this.thumb, 'pointerdown').pipe(
    switchMap((startEvent) => fromEvent(document, 'pointermove', { passive: true })
    // transform to proper positioning
  ));
}

を使用することが重要ですdefer。これにより、オブザーバブルがサブスクライブされている場合にのみ解決されるようになります。これは、パイプがサブスクライブするngAfterViewInitときに、 がトリガーされる前に発生しますasync。 を使用しているためstatic: true、 はthis.thumbすでに入力されています。

おすすめ記事