Hier ist mein Code, der einen Fehler gibt, der den Eigenschaftstitel undefined nicht lesen kann.
Übergeordnete Komponente
import { Child } from './child.component';
@Component({
selector: 'parent',
})
export class ParentComponet implements OnInit, AfterViewInit {
constructor(){}
@ViewChild(Child) child: Child;
ngAfterViewInit(){
console.log("check data", this.child.title)
}
}
Und die untergeordnete Komponente ist.
@Component({
selector: 'child',
})
export class ChildComponet {
public title = "hi"
constructor(){}
}
routing.module.ts ist wie
{
path: "",
component: ParentComponent,
children: [
{
path: '/child',
component: ChildComponent
}
]
}
Und gibt Fehler, ist
ERROR TypeError: Cannot read property 'title' of undefined(…)
Ich denke, dass Sie 'template' oder 'templateUrl' in Bezug auf das Erstellen einer Komponente vermissen
ParentComponent
import { ChildComponent } from './child.component'; // {ChildComponent} not {Child} as we are referencing it to the exported class of ChildComponent
@Component({
selector: 'parent',
template: `<child></child>`
})
export class ParentComponet implements OnInit, AfterViewInit {...}
ChildComponent
@Component({
selector: 'child',
template: `<h1>{{ title }}</h1>`
})
export class ChildComponent {...} // Be sure to spell it right as yours were ChildComponet - missing 'n'
UPDATE gemäß der Erläuterung des Benutzers in diesem Thread
Hatte eine Stackblitz-Demo hinzugefügt als Referenz (Überprüfen Sie die Konsole)
Wenn Sie auf die ChildComponent zugreifen möchten, die unter dem <router-outlet>
der übergeordneten Komponente gerendert wird, können Sie dies durch Verwendung von (aktivieren) der unterstützten Eigenschaft von router-outlet tun:
Ein Router-Ausgang gibt jedes Mal ein Aktivierungsereignis aus, wenn eine neue Komponente instanziiert wird
ParentComponent-Vorlage
@Component({
selector: 'parent',
template: `<router-outlet (activate)="onActivate($event)"></router-outlet>`
})
export class ParentComponent {
onActivate(event): void {
console.log(event); // Sample Output when you visit ChildComponent url
// ChildComponent {title: "hi"}
console.log(event.title); // 'hi'
}
}
Das Ergebnis unterscheidet sich je nach besuchter Seite unter den Kindern Ihrer Eltern.
Wenn Sie Child1Component besuchen, erhalten Sie die Instanz
Child1Component {title: "hi"}
.Wenn Sie Child2Component besuchen, erhalten Sie dessen Instanz
Child2Component {name: "Angular"}
.Diese Ergebnisse werden dann in der onActivate (event) -Konsole Ihrer ParentComponent angezeigt, damit Sie auf zugreifen können.
So soll es nicht funktionieren. Sie können ChildComponent
nur in Ihrer ParentComponent
NUR abrufen, wenn Sie das <app-child></app-child>
-Tag in Ihrer ParentComponent
-Vorlage haben.
Etwas wie das:
...
<app-child></app-child>
...
Da Sie jedoch untergeordnetes Routing verwenden und ChildComponent
auf den router-outlet
Ihres ParentComponent
geladen wird, haben Sie mit ViewChild
keinen Zugriff darauf.
PS: Sie haben nur Zugriff auf ngAfterViewInit
, da ViewChild
nur dann als sicher erachtet werden kann, nachdem die View geladen wurde:
import { Component, OnInit, ViewChild } from '@angular/core';
import { ChildComponent } from '../child/child.component';
...
@Component({...})
export class ParentComponent implements OnInit {
@ViewChild(ChildComponent) childComponent: ChildComponent;
...
ngAfterViewInit() {
console.log(this.childComponent);
}
}
Hier ist ein Working Sample StackBlitz für Ihren Ref, der Ihr Szenario in beiden Fällen veranschaulicht.
PS: Um die ChildComponent
-Eigenschaften in Ihrem ParentComponent
zu erhalten, müssen Sie beim Routing entweder ein SharedService
verwenden, oder Sie müssen die ChildProperty in der Route als QueryParam übergeben und in der ParentComponent mithilfe von lesen ActivatedRoute
Dies macht zwar nicht viel Sinn, aber in Ihrer ChildComponent
können Sie einen Link haben, der den Benutzer mit der title
-Eigenschaft, die als queryParam
übergeben wird, an die ChildComponent weiterleitet. Etwas wie das:
<a
[routerLink]="['/child']"
[queryParams]="{title: title}">
Go To Child Route With Query Params
</a>
Und in Ihrem ParentComponent
haben Sie Zugriff auf ActivatedRoute
wie folgt:
...
import { ActivatedRoute } from '@angular/router';
...
@Component({...})
export class ParentComponent implements OnInit {
...
constructor(
private route: ActivatedRoute,
...
) { }
ngOnInit() {
this.route.queryParams.subscribe(queryParams => {
console.log('queryParams[`title`]', queryParams['title']);
});
...
}
...
}
SharedService
verwendenErstellen Sie einfach eine SharedService
mit einer private
BehaviorSubject
, die als Observable
verfügbar gemacht würde, indem Sie die asObservable
-Methode aufrufen. Ihr Wert kann festgelegt werden, indem eine Methode (setChildProperty
) verfügbar gemacht wird, die im Wesentlichen die next
-Methode mit dem aktualisierten childProperty
-Wert aufruft:
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable()
export class SharedService {
private childProperty: BehaviorSubject<string> = new BehaviorSubject<string>(null);
childProperty$: Observable<string> = this.childProperty.asObservable();
constructor() { }
setChildProperty(childProperty) {
this.childProperty.next(childProperty);
}
}
Sie können es dann sowohl in Ihr ParentComponent
als auch in Ihr ChildComponent
injizieren:
In ChildComponent
setzen Sie den Wert:
import { Component, OnInit } from '@angular/core';
import { SharedService } from '../shared.service';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
public title = "hi"
constructor(private sharedService: SharedService) { }
ngOnInit() {
this.sharedService.setChildProperty(this.title);
}
}
Und in Ihrer ParentComponent
erhalten Sie den Wert:
...
import { SharedService } from '../shared.service';
@Component({...})
export class ParentComponent implements OnInit {
...
constructor(
...,
private sharedService: SharedService
) { }
ngOnInit() {
...
this.sharedService.childProperty$.subscribe(
childProperty => console.log('Got the Child Property from the Shared Service as: ', childProperty)
);
}
...
}
Stellen Sie sicher, dass Sie in Ihrer parent.component.html
-Vorlage das <child></child>
-Tag hinzugefügt haben.