@ViewChild 在 *ngIf 中 [英] @ViewChild in *ngIf
问题描述
问题
显示模板中相应元素后获得@ViewChild
的最优雅方式是什么?
下面是一个例子.也可以使用 Plunker.
Component.template.html:
<div #contentPlaceholder></div>
Component.component.ts:
export class AppComponent {显示=假;@ViewChild('contentPlaceholder', { read: ViewContainerRef }) viewContainerRef;展示() {this.display = true;console.log(this.viewContainerRef);//不明确的setTimeout(() => {console.log(this.viewContainerRef);//好的}, 1);}}
我有一个组件,它的内容默认是隐藏的.当有人调用 show()
方法时,它变得可见.但是,在 Angular 2 更改检测完成之前,我无法引用 viewContainerRef
.我通常将所有必需的操作包装到 setTimeout(()=>{},1)
中,如上所示.有没有更正确的方法?
我知道 ngAfterViewChecked
有一个选项,但它会导致太多无用的调用.
ANSWER (Plunker)
为 ViewChild 使用 setter:
private contentPlaceholder: ElementRef;@ViewChild('contentPlaceholder') 设置内容(内容:ElementRef) {if(content) {//初始 setter 被调用为 undefinedthis.contentPlaceholder = 内容;}}
一旦 *ngIf
变为 true
,就会使用元素引用调用 setter.
注意,对于 Angular 8,您必须确保设置 { static: false }
,这是其他 Angular 版本中的默认设置:
@ViewChild('contentPlaceholder', { static: false })
注意:如果 contentPlaceholder 是一个组件,您可以将 ElementRef 更改为您的组件类:
private contentPlaceholder: MyCustomComponent;@ViewChild('contentPlaceholder') 设置内容(内容:MyCustomComponent) {if(content) {//初始 setter 被调用为 undefinedthis.contentPlaceholder = 内容;}}
Question
What is the most elegant way to get @ViewChild
after corresponding element in template was shown?
Below is an example. Also Plunker available.
Component.template.html:
<div id="layout" *ngIf="display">
<div #contentPlaceholder></div>
</div>
Component.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);
}
}
I have a component with its contents hidden by default. When someone calls show()
method it becomes visible. However, before Angular 2 change detection completes, I can not reference to viewContainerRef
. I usually wrap all required actions into setTimeout(()=>{},1)
as shown above. Is there a more correct way?
I know there is an option with ngAfterViewChecked
, but it causes too much useless calls.
ANSWER (Plunker)
Use a setter for the ViewChild:
private contentPlaceholder: ElementRef;
@ViewChild('contentPlaceholder') set content(content: ElementRef) {
if(content) { // initially setter gets called with undefined
this.contentPlaceholder = content;
}
}
The setter is called with an element reference once *ngIf
becomes true
.
Note, for Angular 8 you have to make sure to set { static: false }
, which is a default setting in other Angular versions:
@ViewChild('contentPlaceholder', { static: false })
Note: if contentPlaceholder is a component you can change ElementRef to your component Class:
private contentPlaceholder: MyCustomComponent;
@ViewChild('contentPlaceholder') set content(content: MyCustomComponent) {
if(content) { // initially setter gets called with undefined
this.contentPlaceholder = content;
}
}
这篇关于@ViewChild 在 *ngIf 中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!