首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@ViewChild in *ngIf

@ViewChild in *ngIf
EN

Stack Overflow用户
提问于 2016-09-07 10:08:52
回答 19查看 170.4K关注 0票数 362

问题

在模板中显示了相应的元素之后,获得@ViewChild的最优雅的方法是什么?

下面是一个例子。也可以使用柱塞

Component.template.html:

代码语言:javascript
复制
<div id="layout" *ngIf="display">
  <div #contentPlaceholder></div>
</div>

Component.component.ts:

代码语言:javascript
复制
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有一个选项,但是它会导致太多无用的调用。

回答(柱塞)

EN

回答 19

Stack Overflow用户

回答已采纳

发布于 2016-12-12 07:04:52

为ViewChild使用一个设置器:

代码语言:javascript
复制
 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 },这是其他角版本中的默认设置:

代码语言:javascript
复制
 @ViewChild('contentPlaceholder', { static: false })

注意:如果contentPlaceholder是一个组件,您可以将ElementRef更改为组件类:

代码语言:javascript
复制
  private contentPlaceholder: MyCustomComponent;

  @ViewChild('contentPlaceholder') set content(content: MyCustomComponent) {
     if(content) { // initially setter gets called with undefined
          this.contentPlaceholder = content;
     }
  }
票数 525
EN

Stack Overflow用户

发布于 2017-09-04 20:46:22

克服这一问题的另一种方法是手动运行更改检测器。

首先注入ChangeDetectorRef

代码语言:javascript
复制
constructor(private changeDetector : ChangeDetectorRef) {}

然后,在更新控制*ngIf的变量后调用它。

代码语言:javascript
复制
show() {
        this.display = true;
        this.changeDetector.detectChanges();
    }
票数 153
EN

Stack Overflow用户

发布于 2019-08-15 10:45:34

角8+

您应该添加{ static: false }作为@ViewChild的第二个选项。这将导致在运行更改检测运行后解析查询结果,从而允许在值更改后更新@ViewChild

示例:

代码语言:javascript
复制
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

票数 108
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39366981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档