简体   繁体   English

Angular6 @ViewChild 未定义与 ngIf

[英]Angular6 @ViewChild undefined with ngIf

I've a problem using @ViewChild with a component showed through ngIf.我在将 @ViewChild 与通过 ngIf 显示的组件一起使用时遇到问题。 I found various solutions but no one usefull for me.我找到了各种解决方案,但没有一个对我有用。 This is my main component, consisting of various step (I showed only 2 in code for brevity) with a button for forward navigation and a button to reset the component returning on first step.这是我的主要组件,由多个步骤组成(为简洁起见,我在代码中只显示了 2 个),带有一个用于向前导航的按钮和一个用于重置在第一步返回的组件的按钮。 First step is showed on page opening:第一步显示在页面打开时:

...
<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
    }
...
}

During steps navigation the reference to firstChildComp is lost and when reset() is called, childComp results undefined.在步骤导航期间,对 firstChildComp 的引用丢失,并且在调用 reset() 时,childComp 结果未定义。 I know the cause is ngIf, so I tryed to use ngAfterViewInit:我知道原因是 ngIf,所以我尝试使用 ngAfterViewInit:

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

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

but it doesn't resolve my problem.但它不能解决我的问题。 Any suggestion?有什么建议吗?

As Angular's Doc says:正如 Angular 的文档所说:

"True to resolve query results before change detection runs. If any query results are inside a nested view (such as *ngIf), the query is resolved after change detection runs." “在更改检测运行之前解析查询结果为真。如果任何查询结果在嵌套视图内(例如 *ngIf),则在更改检测运行后解析查询。”

So, passing the param { static: false } to @ViewChild resolve the problem, as it is accessed on ngAfterViewInit, instead on { static: true } is accessed before change detection runs so on ngOnInit.因此,将参数{ static: false }传递给 @ViewChild 可以解决问题,因为它是在 ngAfterViewInit 上访问的,而不是在{ static: true }上访问,然后在更改检测运行之前在 ngOnInit 上访问。

ngIf will remove you component from the DOM. ngIf 将从 DOM 中删除你的组件。 So it becomes undefined.所以它变得不确定。 If you use [hidden]="!showFirstChild" instead, it will be only hidden, and will be available in the component.如果您改用[hidden]="!showFirstChild" ,它只会被隐藏,并且在组件中可用。

Here is a stackblitz where you can check this.这是一个stackblitz ,您可以在其中进行检查。

Try running change detection in between to ensure the DOM template is reading the DOM after the change in reset.尝试在两者之间运行更改检测,以确保 DOM 模板在重置更改后读取 DOM。

In template:在模板中:

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

In controller:在控制器中:

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) {}

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

      this.fcomp = this.firstChildComp;
  }

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

ChangeDetectorRef Documentation for further reading. ChangeDetectorRef 文档以供进一步阅读。

If you are still looking for an answer, you can also try setting the static flag value on true.如果您仍在寻找答案,您也可以尝试将静态标志值设置为 true。 That will make the child component viewContainerRef loads depending on the ngIf value.这将使子组件 viewContainerRef 根据viewContainerRefngIf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM