问题
在模板中显示了相应的元素之后,获得@ViewChild的最优雅的方法是什么?
下面是一个例子。也可以使用柱塞。
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);
}
}默认情况下,我有一个包含其内容的组件。当有人调用show()方法时,它变得可见。然而,在角度2变化检测完成之前,我不能参考viewContainerRef。我通常将所有必需的操作打包到setTimeout(()=>{},1)中,如上面所示。有更正确的方法吗?
我知道ngAfterViewChecked有一个选项,但是它会导致太多无用的调用。
回答(柱塞)
发布于 2016-12-12 07:04:52
为ViewChild使用一个设置器:
private contentPlaceholder: ElementRef;
@ViewChild('contentPlaceholder') set content(content: ElementRef) {
if(content) { // initially setter gets called with undefined
this.contentPlaceholder = content;
}
}一旦*ngIf变成true,就用元素引用调用setter。
注意,对于角8,您必须确保设置{ static: false },这是其他角版本中的默认设置:
@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;
}
}发布于 2017-09-04 20:46:22
克服这一问题的另一种方法是手动运行更改检测器。
首先注入ChangeDetectorRef
constructor(private changeDetector : ChangeDetectorRef) {}然后,在更新控制*ngIf的变量后调用它。
show() {
this.display = true;
this.changeDetector.detectChanges();
}发布于 2019-08-15 10:45:34
角8+
您应该添加{ static: false }作为@ViewChild的第二个选项。这将导致在运行更改检测运行后解析查询结果,从而允许在值更改后更新@ViewChild。
示例:
export class AppComponent {
@ViewChild('contentPlaceholder', { static: false }) contentPlaceholder: ElementRef;
display = false;
constructor(private changeDetectorRef: ChangeDetectorRef) {
}
show() {
this.display = true;
// Required to access this.contentPlaceholder below,
// otherwise contentPlaceholder will be undefined
this.changeDetectorRef.detectChanges();
console.log(this.contentPlaceholder);
}
}Stackblitz示例:https://stackblitz.com/edit/angular-d8ezsn
https://stackoverflow.com/questions/39366981
复制相似问题