等待RxJS可观察到时在Angular中显示加载指示器

时间:2018-12-13 18:01:44

标签: angular rxjs observable

我有一个Angular组件,该组件侦听要更改用户ID的route参数,并在加载时加载用户详细信息。用户详细信息需要花费几秒钟的时间才能从API返回数据。

如果我正在查看用户A的详细信息,然后单击以查看用户B的详细信息,它将继续显示用户A,直到单击后几秒钟返回用户B的详细信息。有什么办法可以显示正在加载的指示器,或者在为用户B检索数据时将其清空?

用户详细信息组件:

ngOnInit(): void {
  this.userDetails = this.route.paramMap.pipe(
    switchMap((params: ParamMap) => this.userService.getUserDetails(+params.get('userId')))
  );
}

用户详细信息模板:

<div *ngIf="userDetails | async as userDetails">
  <h1>{{userDetails.firstName}} {{userDetails.lastName}}</h1>
</div>

如果该内部switchMap当前正在运行,我希望用户详细信息div为空白或显示某种加载指示符。我知道一个选项是在switchMap之前设置为true,在switchMap之后设置为false,并在div的* ngIf中使用该变量,但我希望可以采用一种轻松的方式在每种情况下都加载变量。

我有一个StackBlitz示例: https://stackblitz.com/edit/angular-ng-busy-yxo1gu

目标是当我单击用户B按钮时,在加载用户B时用户A信息应消失。我的应用程序中有数十种这种情况,因此我正在寻找最干净的方法。

3 个答案:

答案 0 :(得分:3)

如果只希望内容消失,则可以在开始获取其他用户时发出null这样的消息:

this.userDetails = this.userId.asObservable().pipe(
  switchMap(id => merge(
    of(null),
    this.getUserDetails(id)
  )),
);

merge可观察的创建方法将重新发射null,然后等待getUserDetails完成。您甚至不需要ng-busy

您的更新演示:https://stackblitz.com/edit/angular-ng-busy-vwteyf?file=src/app/app.component.ts

答案 1 :(得分:2)

您可以更改* ngIf

ngIf="userDetails | async as userDetails else #loading"

然后

<div #loading>
  loading...
</div>

Reference

答案 2 :(得分:1)

您可以使用ng-busy(或那里的任何其他npm组件)在应用程序的每个http调用中显示加载指示符(在您的情况下是应许或可观察的)。

编辑:关于您正在使用Observable的事实,可以使用.toPromise以便与ng-Busy一起使用。修改了DEMO,向您展示了如何操作。

这是您的代码中Minimal, Complete, and Verifiable example的ng-busy。