使用Angular异步管道来订阅Observable

时间:2020-07-23 21:41:29

标签: angular asynchronous ionic-framework rxjs-observables

我成功地在Angular / Ionic应用程序中的几个不同组件中订阅了一个可观察对象。但是,因为我是手动执行的,所以这也意味着我需要手动取消订阅,这是我目前在ngOnDestroy()生命周期挂钩中所做的。

正在运行的组件代码实现如下所示:

  getPlayerStats() {
    this.playerSubscription = this.mainService.getPlayerStats(this.username).subscribe(
      user => {
        this.user = user;
      },
      error => this.errorMsg = error
    );
  }

我对该组件的查看代码如下:

<ion-card *ngIf="user">
  ... display user info
</ion-card>

这里调用的服务方法如下:

  getPlayerStats(username: string) {
    const req = `users/stats/${username}`;
    return this.apiService.sendRequest(req);
  }

我想做的,但是很难上班,正在使用async管道在HTML视图中进行订阅。那会更干净,因为那样我就不必太冗长,也不必在使用此组件的组件中手动进行订阅和退订。我的理解是,正是出于这些原因,这也是处理这些情况的推荐方法。

该代码是什么样的?我试过了,但是没用:

getPlayerStatus() {
  this.user = this.mainService.getPlayerStats(this.username);
}

在我的HTML视图中,我这样做:

<ion-card *ngIf="user | async">
  ... display user info
</ion-card>

但是正如我所说,这是行不通的。我需要在这里更改什么?如何调用服务getPlayerStats()方法,但是如何使用异步管道在组件视图中处理订阅?

1 个答案:

答案 0 :(得分:4)

您可以尝试使用*ngIf指令的as签名。它还允许您通过单个async多次使用通知。假设可观察对象是HTTP调用,请记住,每个async管道都会触发一个新请求,因为它是一个冷的可观察对象。

通常的做法是在可观察变量后缀一个美元符号。因此,紧随其后的是控制器

user$: any;

getPlayerStatus() {
  this.user$ = this.mainService.getPlayerStats(this.username).pipe(
    catchError(error => {       // <-- HTTP error handling 
      this.errorMsg = error;
      return of(error);         // <-- return an observable from `catchError`
    }
  );
}

使用此变量的模板为

<ng-container *ngIf="(user$ | async) as user">
  <ion-card>
    ... display user info
    {{ user | json }}
    {{ user.name }}
    ...
  </ion-card>
</ng-container>

不用说,但是要使此工作正常,应该至少调用一次getPlayerStatus()函数以初始化this.user$变量。