新しい 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: false
Angular 9 のデフォルトのフォールバック動作になります。続きを読むここそしてここ
この{ static: true }
オプションは、埋め込みビューをオンザフライで作成できるようにするために導入されました。動的にビューを作成し、 にアクセスしたい場合、エラーが発生するためTemplateRef
ではアクセスできません。static フラグを true に設定すると、ngOnInit でビューが作成されます。ngAfterViewInit
ExpressionHasChangedAfterChecked
それにもかかわらず:
その他のほとんどの場合、 を使用するのがベストプラクティスです
{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
すでに入力されています。