角度2或4,哪个生命周期钩是对的?

时间:2017-09-13 06:38:26

标签: angular

在我的 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的解决方案最容易理解/遵循并且没有错误。

3 个答案:

答案 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