显示包含加载和错误情况的数据



在 Angular 中,考虑到加载状态和错误情况,在视图中显示数据的可靠方法是什么?

假设我们正在从后端获取文档集合,并希望使用 Angular 在我们的视图中显示这些文档。我想考虑 3 个状态。对于其中每个状态,我想向用户显示一条消息:

  1. 正在加载您的数据...
  2. 尝试检索数据时出错!
  3. 数据检索成功!

目前,我正在做以下工作。我面临的问题是"加载"和"错误"消息在加载阶段都会短暂显示。

我想知道其他人如何解决这个常见用例?是否可以通过为myDocs变量分配不同的值来做到这一点,或者我是否必须引入另一个变量?

TS

export class MyDocsComponent implements OnInit {
    myDocs: IMyDoc | null;
    ngOnInit() {
        // get myDocs
        this.myDocsService.getMyDocs()
        // if success
        .then( myDocs => { this.myDocs = myDocs; })
        // if error: could not get myDocs from service
        .catch( error => {
            // what should go in here
            // and how should this be checked in the view
            // to display an error message to the user
            // if the data could not be retrieved
            // while also being able to display a loading message beforehand
            // currently, I am doing:
            this.myDocs = null;
            // however, this leads to the error message 
            // incorrectly being displayed 
            // while loading the data
        });
    }
}

.HTML

<!-- loading -->
<div class="loading" *ngIf="!myDocs">
    Loading your data...
</div>
<!-- error -->
<div class="error" *ngIf="myDocs==null">
    Error trying to retrieve your data!                         
</div>
<!-- success -->
<div class="success" *ngIf="myDocs">
    Data retrieved successfully!
    <div class="list" *ngFor="let d of myDocs">{{ d.title }}</div>
</div>

试试这样的事情

组件.ts

export class MyDocsComponent implements OnInit {
  myDocs: IMyDoc | null;
  state: 'loading' | 'loaded' | 'error' = 'loading';
  isLoading() {
    return this.state === 'loading';
  }
  isError() {
    return this.state === 'error';
  }
  isLoaded() {
    return this.state === 'loaded';
  }
  ngOnInit() {
    this.myDocsService.getMyDocs()
      .then(myDocs => {
        this.myDocs = myDocs;
        this.state = 'loaded';
      })
      .catch(error => {
        console.log(error);
        this.state = 'error';
      });
  }
}

组件.html

<div *ngIf="isLoading"  class="loading">
  Loading your data...
</div>
<div *ngIf="isError" class="error">
  Error trying to retrieve your data!
</div>
<div *ngIf="isSuccess" class="success" >
  Data retrieved successfully!
  <div class="list" *ngFor="let d of myDocs"> {{ d.title }}
  </div>
</div>

这是处理相同问题的另一种方法。我正在按照OP的要求将其移至另一个答案。不要投赞成票。

这使用了一些更高级的角度API,例如

  • async pipe
  • <ng-container>
  • as *ngIf表达式中的关键字
  • else loading<ng-template #loading>相结合

组件.ts

  export class MyDocsComponent implements OnInit {
    myDocs$: Promise < IMyDoc | string > ;
    ngOnInit() {
      this.myDocs$ = this.myDocsService.getMyDocs()
        .catch(error => {
          console.log(error);
          return 'there was an error';
        });
    }
    isError(resp: IMyDoc | string) {
      return typeof resp === 'string';
    }

    isSuccess(resp: IMyDoc | string) {
      return typeof resp !== 'string';
    }
  }

组件.html

<div *ngIf="myDocs$ | async as myDocs; else loading">
  <ng-container *ngIf="isSuccess(myDocs)" >
    <div class="success"
       Data retrieved successfully!
       <div class="list" *ngFor="let d of myDocs"> {{ d.title }}       
       </div>
    </div>
  </ng-container>
  <ng-container *ngIf="isError(myDocs)">
    <div *ngIf="isError" class="error">
      Error trying to retrieve your data!
    </div>
  </ng-container>
</div>
<ng-template #loading>
  <div *ngIf="isLoading" class="loading">
    Loading your data...
  </div>
</ng-template>

最新更新