Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度2或4,哪个生命周期挂钩是正确的?_Angular - Fatal编程技术网

Angular 角度2或4,哪个生命周期挂钩是正确的?

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(

在myItemDetailComponent中

我有以下代码:

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)
  });
}