Angular6 @ViewChild undefined with ngIf

情到浓时终转凉″ 提交于 2020-05-28 18:37:39

问题


I've a problem using @ViewChild with a component showed through 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. 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. I know the cause is ngIf, so I tryed to use ngAfterViewInit:

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

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

but it doesn't resolve my problem. Any suggestion?


回答1:


As Angular's Doc says:

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

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.




回答2:


Try running change detection in between to ensure the DOM template is reading the DOM after the change in reset.

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.




回答3:


ngIf will remove you component from the DOM. So it becomes undefined. If you use [hidden]="!showFirstChild" instead, it will be only hidden, and will be available in the component.

Here is a stackblitz where you can check this.




回答4:


If you are still looking for an answer, you can also try setting the static flag value on true. That will make the child component viewContainerRef loads depending on the ngIf value.



来源:https://stackoverflow.com/questions/55610047/angular6-viewchild-undefined-with-ngif

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!