在我的ItemDetailComponent里
我有以下代码:
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)
)
}在我的ItemService上:
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呈现--转换错误,因为 item 仍然是未定义的。但是,当从数据库中检索到项时,以后就可以工作了。
有什么解决办法吗?我是不是用错了生命周期挂钩?即使成功了-我觉得我能做得更好。有什么建议/解决方案吗?
编辑:谢谢您的所有回答,但我相信Srapyan的解决方案是最简单的理解/遵循并且没有错误。
发布于 2017-09-13 06:40:08
对于每个生命周期挂钩,在DOM准备就绪之前无法检索项目。一种解决方案是使用ngIf指令隐藏标记的这一部分,直到得到所需的数据为止。
,例如
<div ngIf="yourData">
<p>{{ yourData.ImagePath }}</p>
</div>发布于 2017-09-13 06:41:21
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)
)
});
}在html模板中使用类似{{item?.ImagePath}}的安全运算符?
发布于 2017-09-13 08:35:14
另一个答案是在订阅中使用订阅,这并不是真正的RxJS最佳实践。您将更好地使用flatMap操作符,它将可观测到的项转换为可观测的项,然后将这些项的排放量平缓到单个可观测的位置。http://reactivex.io/documentation/operators/flatmap.html
item: Observable<Item>;
param: string;
ngOnInit() {
this.item = this.activatedRoute.params.flatMap((params: Params) => {
this.param = params.id;
return this.itemService.getItem(this.param)
});
}在HTML中,您可以在HTML中使用异步管道{{ item | async }},这将处理可观察到的项的订阅和取消订阅。https://angular.io/api/common/AsyncPipe
https://stackoverflow.com/questions/46190481
复制相似问题