javascript - ViewChild är odefinierad i angular 13
Jag försöker anropa en vybarn på en barnkomponent från föräldern och får undefined i konsolen.
se bilden se också stackblazen för samma
https://stackblitz.com/edit/angular-ivy-k4m2hp?file=src%2Fapp%2Fhello.component.ts
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { TestChildComponent } from './test-child/test-child.component';
@Component({
selector: 'hello',
template: `<h1>this is Hello component {{name}}!</h1>`,
styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent {
@Input() name: string;
@ViewChild('TestChildComponent') testChildComponent: TestChildComponent
ngOnInit() {
console.log('calling ngOninit in hello component');
console.log('going to call test child instance this.TestChildComponent.ngOninit')
console.log(this.testChildComponent);
}
}
Vänligen hjälp till att få barnkomponenten
this.testChildComponent
Så att jag kan kalla ngOnInit i barnet från föräldern.
this.testChildComponent.ngOnInit()
Svar #1
ViewChild-elementreferensen kan nås tidigast i ngAfterViewInit()-cykeln.
Angular-dokumentationen säger att vi bör använda barnkomponenten som injiceras av ViewChild i ngAfterViewInit. Men ibland kan du inte ens få tag på den i ngAfterViewInit. Anledningen är att barnkomponenten ännu inte har skapats när AfterViewInit-hooken körs. I ett sådant fall skulle du behöva vänta längre (att använda en setTimeout skulle fungera men det är en dålig idé). Ett annat alternativ skulle vara att låta barnet sända något till föräldern, så att den får veta att barnet har renderats och sedan kan föräldern fråga efter det.
Men i ditt fall är det så att syskonet HelloComponent vill fråga syskonet TestChildComponent, det kan det inte göra. TestChildComponent finns helt enkelt inte inom räckvidden för HelloComponent. Den enklaste lösningen skulle vara att fråga TestChildComponent från föräldern AppComponent.
Du bör också lägga till #TestChildComponent för att få åtkomst till ref:en.
<app-test-child #TestChildComponent childname="{{ name }}"></app-test-child>
Fungerande exempel: https://stackblitz.com/edit/angular-ivy-j5ceat?file=src%2Fapp%2Fapp.component.html
Svar #2
om du anger din viewChild { static: true } kommer du att kunna få åtkomst till den i ngOnInit
men i ditt exempel är problemet på grund av att testChildComponent är ett barn till app.component och inte hello.component
<app-test-child childname="{{ name }}" #test></app-test-child>
app.component.ts
import { Component, VERSION, ViewChild } from '@angular/core';
import { TestChildComponent } from './test-child/test-child.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'this is from app compoenent';
@ViewChild('test', { static: true }) testChildComponent: TestChildComponent;
ngOnInit() {
console.log('calling ngOninit in app component');
console.log(this.testChildComponent);
}
}
Om du vill få åtkomst till testChildComponent från hello.component måste du skicka komponenten som en input till sample
följande ett fungerande exempel på åtkomst till testChildComponent
https://stackblitz.com/edit/angular-ivy-tvwukg?file=src%2Fapp%2Fapp.component.html

