【问题标题】:Need help to refactor to an async pipe in Angular需要帮助来重构 Angular 中的异步管道
【发布时间】:2021-01-26 04:49:04
【问题描述】:

我需要一些帮助来重构我对异步管道的方法和服务调用。

这是我的组件和服务中的内容

///// component ///// 
bands: Iband[];

getbands() {
    this.membersService.getbandsForMember(this.member.id).subscribe(response => {
        this.bands = response;
    }, error => {
      console.log(error);
    });
}
  
///// service ///// 
  
getbandsForMember(id: number) {
   return this.http.get<Iband[]>(this.baseUrl + 'members/' + id + '/memberbands');
}

这是我遇到的一些麻烦。 除了服务,我觉得我说得对,不知道怎么修改。

///// component /////
bands$: Observable<Iband[]> ;

getbands() {
  this.membersService.getbandsForMember(this.member.id).subscribe(response => {
      this.bands$ = response;
    }, error => {
      console.log(error);
    });
}


///// service ///// 
getbandsForMember(id: number) {
  return this.http.get<Iband[]>(this.baseUrl + 'members/' + id + '/memberbands').pipe(
    map((bands: Iband[]) => {
      return bands;
    })
  );
}

【问题讨论】:

  • map(bands =&gt; bands) 是无操作的。而且您正在将解析的值分配给属性,而不是可观察的 - 大概您遇到了类型错误(尽管minimal reproducible example 会澄清)。你只想要this.bands$ = this. membersService.getbandsForMember(this.member.id)吗?
  • 所以删除地图()?我将方法的返回值分配给 this.bands$ 并且我没有错误。我还需要删除 map() 吗?

标签: angular typescript asynchronous observable


【解决方案1】:
  1. RxJS map 运算符用于转换 observable 发出的值。如果您不转换响应,则不需要。

  2. Angular async 管道应该与可观察对象一起使用。您将类型定义为bands$: Observable&lt;Iband[]&gt; 是正确的。但不需要订阅。 async 管道将订阅 observable。

服务

getbandsForMember(id: number): Observable<Iband[]> {
  return this.http.get<Iband[]>(this.baseUrl + 'members/' + id + '/memberbands');
}

组件

bands$: Observable<Iband[]> ;

getbands() {
  this.band$ = this.membersService.getbandsForMember(this.member.id);
}

模板

<ng-container *ngIf="(bands$ | async) as bands">
  <!-- use `bands` emission from the observable -->
  {{ bands | json }}
</ng-container>

更新:在组件中设置成员变量

当在模板中触发async 管道时,您可以在组件中使用tapmap 运算符来执行一些副作用。如果传入不需要转换,则使用tap,否则使用map

控制器

bands$: Observable<Iband[]> ;

getbands() {
  this.band$ = this.membersService.getbandsForMember(this.member.id).pipe(
    tap(response => {
      console.log('got bands in component:', response);
      this.skip = true; // <-- set some variable
      // set some other variables and call some functions
    })
  );
}

模板

<ng-container *ngIf="(bands$ | async) as bands">
  <!-- use `bands` emission from the observable -->
  {{ bands | json }}
</ng-container>

【讨论】:

  • 嗨,迈克尔。快速提问 - 如果我想在 getbandsForMember() 返回数据后做一些逻辑(设置 1 或 2 个其他组件变量),我会在调用服务方法后立即将其放入吗?我问的原因是因为这个调用不是异步的。我想等到服务恢复,那么数据返回后我该怎么做呢?前任。在我的个人资料页面上,我获取评论,在评论进来后,通过用户点击,我想更新一个“跳过”值,这样我下次就不会获取相同的评论了。
  • @user1186050:您可以在组件中使用tap 运算符来做一些效果。我已经更新了答案。看看它是否适合你。
  • 嗨,我还有几个问题,在这里发布了一个新主题:stackoverflow.com/questions/64309977/…
  • @user1186050:从现在删除的答案中,我假设您已经解决了 (reviews$ | async)?.length 的问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多