在我的 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 时起作用。
有解决方案吗?我使用错误的生命周期钩子吗?即使它有效 - 我觉得我可以做得更好。有什么建议/解决方案吗?
编辑:感谢您的所有答案,但我相信Suren Srapyan的解决方案最容易理解/遵循并且没有错误。
答案 0 :(得分:1)
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}}
安全操作符?
答案 1 :(得分:0)
对于每个生命周期钩子,在DOM准备好之前无法检索到您的项目。一种解决方案是使用ngIf
指令隐藏标记的那一部分,直到获得所需的数据。
例如
<div ngIf="yourData">
<p>{{ yourData.ImagePath }}</p>
</div>
答案 2 :(得分:0)
其他一个答案使用订阅中的订阅,这不是RxJS的最佳实践。你最好使用flatMap运算符 将Observable发出的项目转换为Observables,然后将这些项目的排放量变为单个Observable。 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 }}
来处理Observable项目的订阅和取消订阅。
https://angular.io/api/common/AsyncPipe