ngFor用于延迟数据

时间:2018-09-28 06:36:11

标签: angular

我有一个采用URL参数,调用API并显示数据的组件。最基本的示例:

ngOnInit() {
    this.route.params.subscribe( params => { 
      const id = params.id;     
      this.loadAssets(id);
    });
  }

  loadAssets(id)
  {   
    this.apiService.getAssetGroup(id).subscribe((data) => {
      this.assetGroup  =  data;   
      this.assetSubGroupList = data.assetSubGroupList;
      console.log(this.assetGroup);
    });
  }

在我的html中,我做了一个简单的循环:

<div class="row">
    <div class="col-sm-12 col-lg-12">
        <div *ngFor="let subGroup of assetGroup.assetSubGroupList">
            <div>SubGroup: {{subGroup.name}}</div>
            <div *ngFor="let asset of subGroup.assetList">Asset: {{asset.name}}</div>
        </div>
    </div>
</div>

我想这是Web开发中最常见的一些场景。但是,出现以下错误:

  

无法读取Object.eval上未定义的属性'assetSubGroupList'   [作为updateDirectives](AssetsComponent.html:5)

我最好的猜测是,这是因为在加载页面时assetGroup为null。该页面实际上在数据加载后结束工作,但是我不希望出现第一个错误。我认为必须有一些标准的方法来处理Angular中的这种情况。您是否总是初始化变量,使用ngIf或更智能的方法?

3 个答案:

答案 0 :(得分:1)

?运算符添加到assetGroup

<div *ngFor="let subGroup of assetGroup?.assetSubGroupList">
            <div>SubGroup: {{subGroup.name}}</div>
            <div *ngFor="let asset of subGroup.assetList">Asset: {{asset.name}}</div>
        </div>

答案 1 :(得分:1)

这确实是原因之一,您只能使用此行this.assetSubGroupList = data.assetSubGroupList;进行迭代,因此<div *ngFor="let subGroup of assetSubGroupList">

或者您也可以像这样使用?运算符进行检查

<div *ngFor="let subGroup of assetGroup?.assetSubGroupList">

答案 2 :(得分:1)

请使用async管道。这样一来,您就不必再进行unsubcribe处理,这通常是推荐的做法,并且可以避免任何内存泄漏。

只需在TS类中声明一个名为assetGroup$的属性(理想情况下,我们在$后缀中添加一个可能是Observable类型的值。这只是一个代码约定,您可以阅读有关{ {3}}。然后像这样在loadAssets函数中分配它:

assetGroup$;
...
loadAssets(id) {
  this.assetGroup$ = this.apiService.getAssetGroup(id);
}

然后在模板代码中像这样使用它:

<div class="row">
  <div class="col-sm-12 col-lg-12">
    <div *ngFor="let subGroup of (assetGroup$ | async).assetSubGroupList">
      <div>SubGroup: {{subGroup.name}}</div>
      <div *ngFor="let asset of subGroup.assetList">Asset: {{asset.name}}</div>
    </div>
  </div>
</div>