Angular 角度2或4,哪个生命周期挂钩是正确的?
在myItemDetailComponent中 我有以下代码:Angular 角度2或4,哪个生命周期挂钩是正确的?,angular,Angular,在myItemDetailComponent中 我有以下代码: item: Item; param: string; ngOnInit() { this.activatedRoute.params.subscribe( (params: Params) => { this.param = params.id; }); this.itemService.getItem(this.param).subscribe(
item: Item;
param: string;
ngOnInit() {
this.activatedRoute.params.subscribe( (params: Params) => {
this.param = params.id;
});
this.itemService.getItem(this.param).subscribe(
item => this.item = item,
err => console.error(err)
)
}
在我的项目服务中,我有:
getItem(id: string) {
return this.http.get(`http://localhost:3000/items/${id}`)
.map( (response: Response) => {
const temp = response.json().obj;
const item = new Item(temp.model, temp.description, temp.price, temp.type, temp.imagePath, temp.longDescription, temp._id);
return item;
})
.catch( (error: Response) => Observable.throw(error.json()));
}
因此,TLDR根据id从数据库中检索项目
这是可行的,但问题是HTML组件在我检索数据之前加载。所以我得到了这个错误
ERROR TypeError: Cannot read property 'ImagePath' of undefined
因此,基本上HTML在项目被检索之前呈现-抛出错误,因为项目仍然是未定义的。但当从数据库中检索到项时,它会起作用
有解决办法吗?我是否使用了错误的生命周期挂钩?即使它有效——我觉得我可以做得更好。有什么建议/解决方案吗
编辑:感谢您提供的所有答案,但我相信Suren Srapyan的解决方案是最容易理解/遵循的,并且没有错误。对于每个生命周期挂钩,在DOM准备就绪之前无法检索您的项目。一种解决方案是使用
ngIf
指令隐藏该部分标记,直到获得所需的数据
例如
<div ngIf="yourData">
<p>{{ yourData.ImagePath }}</p>
</div>
{{yourData.ImagePath}
在html模板中,使用类似{
{item?.ImagePath}
的安全操作符?
另一个答案在订阅中使用订阅,这不是真正的RxJS最佳实践。您最好使用flatMap操作符
将可观察到的发射项转换为可观察项,然后将这些发射项展平为单个可观察项。
项:可观察;
参数:字符串;
恩戈尼尼特(){
this.item=this.activatedRoute.params.flatMap((params:params)=>{
this.param=params.id;
返回this.itemService.getItem(this.param)
});
}
在HTML中,您可以在HTML中使用异步管道{{item | Async}}
,它将处理可观察项目的订阅和取消订阅。
这是一个异步调用@SeanUrgel,您需要以异步方式将所有内容放入第一个可观察对象中,或者使用switch或flat map
ngOnInit() {
this.activatedRoute.params.subscribe((params: Params) => {
this.param = params.id;
this.itemService.getItem(this.param).subscribe(
item => this.item = item,
err => console.error(err)
)
});
}
item: Observable<Item>;
param: string;
ngOnInit() {
this.item = this.activatedRoute.params.flatMap((params: Params) => {
this.param = params.id;
return this.itemService.getItem(this.param)
});
}