質問
@ViewChild
テンプレート内の対応する要素が表示された後を取得する最もエレガントな方法は何ですか?
以下に例を示します。また、プランカー利用可能。
コンポーネント.template.html:
<div id="layout" *ngIf="display">
<div #contentPlaceholder></div>
</div>
コンポーネント.component.ts:
export class AppComponent {
display = false;
@ViewChild('contentPlaceholder', { read: ViewContainerRef }) viewContainerRef;
show() {
this.display = true;
console.log(this.viewContainerRef); // undefined
setTimeout(() => {
console.log(this.viewContainerRef); // OK
}, 1);
}
}
デフォルトでコンテンツが非表示になっているコンポーネントがあります。show()
メソッドを呼び出すと、表示されます。ただし、Angular 2 の変更検出が完了するまでは、を参照できませんviewContainerRef
。通常、上記のように、必要なすべてのアクションを にラップしますsetTimeout(()=>{},1)
。より正しい方法はありますか?
にはオプションがあることは知っていますngAfterViewChecked
が、無駄な呼び出しが多すぎます。
答え (プランカー)
ベストアンサー1
ViewChild の setter を使用します。
private contentPlaceholder: ElementRef;
@ViewChild('contentPlaceholder') set content(content: ElementRef) {
if(content) { // initially setter gets called with undefined
this.contentPlaceholder = content;
}
}
*ngIf
になると、要素参照を使用してセッターが呼び出されますtrue
。
{ static: false }
注意: Angular 8 の場合は、他の Angular バージョンではデフォルト設定である を必ず設定する必要があります。
@ViewChild('contentPlaceholder', { static: false })
注: contentPlaceholder がコンポーネントの場合は、ElementRef をコンポーネント クラスに変更できます。
private contentPlaceholder: MyCustomComponent;
@ViewChild('contentPlaceholder') set content(content: MyCustomComponent) {
if(content) { // initially setter gets called with undefined
this.contentPlaceholder = content;
}
}