Angular6 @ViewChild未使用ngIf定义

时间:2019-04-10 10:15:29

标签: angular viewchild

使用@ViewChild和通过ngIf显示的组件时遇到问题。我找到了各种解决方案,但没有一个对我有用。 这是我的主要组件,包括多个步骤(为简便起见,我仅在代码中显示了2个),一个用于向前导航的按钮和一个用于重置第一步返回的组件的按钮。第一步显示在页面打开上:

...
<div class="my-container">
    <first-child *ngIf="showFirtChild"></first-child>
    <second-child *ngIf="showSecondChild"></second-child>
</div>
<button (click)="goToNextStep()"></button>
<button (click)="reset()"></button>
...
export class MainComponent implements OnInit {
    @ViewChild(FirstChild) private firstChildComp: MyFirstChildComponent;
    showFirtChild: boolean = true;

    ngOnInit() {
        //here firstChildComp is defined
    }

    //code for navigate through steps
    reset() {
        this.showFirtChild= true;
        this.firstChildComp.fillTable(); //fillTable is a function defined in MyFirstChildComponent
    }
...
}

在步骤导航期间,对firstChildComp的引用丢失,并且在调用reset()时,childComp结果未定义。我知道原因是ngIf,所以我尝试使用ngAfterViewInit:

ngAfterViewInit() {
    this.fcomp = this.firstChildComp;
}

reset() {
        this.showFirtChild= true;
        this.fcomp .fillTable();
}

但是它不能解决我的问题。 有什么建议吗?

4 个答案:

答案 0 :(得分:1)

ngIf将从DOM中删除您的组件。因此它变得不确定。 如果改用[hidden]="!showFirstChild",它将仅被隐藏,并且在组件中可用。

这里是stackblitz,您可以在此处进行检查。

答案 1 :(得分:1)

尝试在两者之间运行更改检测,以确保DOM模板在重置更改后正在读取DOM。

在模板中:

<first-child #firstChild *ngIf="showFirtChild"></first-child>

在控制器中:

import { ChangeDetectorRef } from '@angular/core';

export class exampleClass implements 
{

@ViewChild('firstChild') public firstChildComp: MyFirstChildComponent;
public fcomp: any;
public showFirtChild: boolean;

constructor(private ref: ChangeDetectorRef,
            //your services) {}

ngAfterViewInit() 
{
    this.showFirtChild = true;
    this.ref.detectChanges();

    this.fcomp = this.firstChildComp;
}

public reset(): void 
{
    this.fcomp.fillTable();
}

ChangeDetectorRef Documentation供进一步阅读。

答案 2 :(得分:1)

如果您仍在寻找答案,也可以尝试将静态标志值设置为true。这将使子组件viewContainerRef取决于ngIf的值。

答案 3 :(得分:1)

正如Angular的医生所说:

  

“在更改检测运行之前正确解析查询结果。如果任何查询结果在嵌套视图中(例如* ngIf),则   运行更改检测后,查询就会解决。”

因此,将参数{ static: false }传递给@ViewChild可以解决此问题,因为在ngOnInit上运行更改检测之前,可以在ngAfterViewInit上访问它,而在{ static: true }上可以访问它。