问题
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