[英]Angular 6 @Viewchild is not working with lazy loading
这是我的代码,给出错误无法读取属性标题undefined。
父组件
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)
}
}
和儿童组件是。
@Component({
selector: 'child',
})
export class ChildComponet {
public title = "hi"
constructor(){}
}
routing.module.ts就像
{
path: "",
component: ParentComponent,
children: [
{
path: '/child',
component: ChildComponent
}
]
}
并且给出了错误
ERROR TypeError: Cannot read property 'title' of undefined(…)
我认为你缺少与创建组件相关的'template'或'templateUrl'
为父级
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'
根据用户对此主题的说明进行更新
已添加Stackblitz演示供您参考(检查控制台)
如果要访问在父组件的<router-outlet>
下呈现的ChildComponent,可以通过利用(激活)router-outlet支持的属性来实现 :
每当实例化新组件时,路由器插座将发出激活事件
ParentComponent的模板
@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'
}
}
结果将根据父母子女下的访问页面而有所不同
如果您访问Child1Component,您将获得其实例
Child1Component {title: "hi"}
如果您访问Child2Component,您将获得其实例
Child2Component {name: "Angular"}
然后,这些结果将反映在ParentComponent的onActivate(事件)控制台上,供您访问
这不是它应该如何工作。 你将只能得到ChildComponent
你ParentComponent
只有当你有<app-child></app-child>
标签在你ParentComponent
模板。
像这样的东西:
...
<app-child></app-child>
...
但是,由于您正在使用子路由,并且ChildComponent
将加载到您的ParentComponent
的router-outlet
,您将无法使用ViewChild
访问它
PS:你只能在ngAfterViewInit
访问它,因为ViewChild
在加载View之后只能被认为是安全的实例化:
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);
}
}
这是您的参考文献的工作示例StackBlitz ,它说明了两种情况下的情景。
PS:要使用Routing获取ParentComponent
的ChildComponent
属性,您必须使用SharedService
或者您必须将路径中的ChildProperty作为QueryParam传递,并使用ActivatedRoute
在ParentComponent中读取它
虽然这没有多大意义,但是在您的ChildComponent
,您可以拥有一个Link,它将用户路由到具有titleParam传递的title
属性的queryParam
。 像这样的东西:
<a
[routerLink]="['/child']"
[queryParams]="{title: title}">
Go To Child Route With Query Params
</a>
在您的ParentComponent
中可以使用ActivatedRoute
访问它,如下所示:
...
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
只需SharedService
private
BehaviorSubject
创建一个SharedService
,通过在其上调用asObservable
方法将其作为Observable
公开。 可以通过公开一个方法( setChildProperty
)来设置它的值,该方法本质上会使用更新的childProperty
值调用next
方法:
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);
}
}
然后,您可以在ParentComponent
和ChildComponent
注入它:
在ChildComponent
设置值:
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);
}
}
在您的ParentComponent
获取值:
...
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)
);
}
...
}
确保在parent.component.html
模板中添加了<child></child>
标记。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.