@ViewChild - Angular 13 上的初始化程序错误

@ViewChild - initializer error on Angular 13

我正在 Angular 13 中创建应用程序。我想使用 @ViewChildParentComponent 调用 ChildComponent 的方法 show(),但是我得到错误。旧的问题和答案在这种情况下不起作用。

Parent:

<app-child #child></app-child>
@ViewChild('child') child: ChildComponent;

showChild() {
   this.child.show();
}

Child:

show(){
  console.log('show');
}

错误:

Property 'child' has no initializer and is not definitely assigned in the constructor.


解决方案 1:

Parent:

@ViewChild('child') child!: ChildComponent;

错误:

TypeError: Cannot read properties of undefined (reading 'show')


解决方案 2:

Parent:

@ViewChild('child') child: ChildComponent = new ChildComponent;

没有错误 工作正常,但我怀疑这是否正确?

你可以这样初始化。我将帮助您解决错误。

@ViewChild('child') child: ChildComponent = {} as ElementRef;

or 

@ViewChild('child') child: ChildComponent = {} as ChildComponent;

解决你的疑惑-

Parent-
<app-child></app-child>
@ViewChild('child') child: ChildComponent;

ngAfterViewInit() {
    // When accessing with ViewChild(), use this lifecycle hook
    // to call methods or for anything related to that component
    this.child.show();
}

Child-
show(){
  console.log('HELLO WORLD');
}

关于访问子组件的额外信息-

通过angular查询子组件、组件的子组件或Html DOM个元素有3种方式,尽早获取查询对象DOM 或组件在 ngAfterViewInit 生命周期钩子中。

1.)根据组件名称查询

app.component.ts

@ViewChild('cardRef', {read: ElementRef}) card1: ElementRef; //by this you can achieve querying over HTML DOM objects
@ViewChild('container') containerDiv: ElementRef;

ngAfterViewInit() {
   console.log("cardRef = ", this.card1);
   console.log("container = ", this.containerDiv);
}

app.component.html

<div class="product" #container>
   <product-card #cardRef></product-card>
</div>

2.)根据引用查询。当您有多张带有不同数据集的卡片并且您想要操作其中任何一张时,这很有用。

app.component.ts

@ViewChild('cardRef1') card1: ProductCardComponent;
@ViewChild('cardRef2') card2: ProductCardComponent;

ngAfterViewInit() {
   console.log("cardRef1 = ", this.card1);
   console.log("cardRef2 = ", this.card2);
}

app.component.html

<div class="product">
   <product-card #cardRef1 [course]="course[0]"></product-card>
   <product-card #cardRef2 [course]="course[1]"></product-card>
</div>

3.)当你查询一个集合列表时,你可以使用@ViewChildren()装饰器。

app.component.ts

@ViewChildren(ProductCardComponent) cards: QueryList<ProductCardComponent>; //QueryList will give a lot methods embedded in it (e.g. first, last, forEach, etc)

ngAfterViewInit() {
   console.log(this.cards.first);  //It will give the object for the first card
}

app.component.html

<div class="product" #container>
   <product-card *ngFor="let product of products"></product-card>
</div>

我希望这能消除你的疑虑。