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

Relaterade artiklar