在其他异步管道中使用异步管道

时间:2019-07-04 10:04:38

标签: angular rxjs observable

我想在角度模板中使用异步管道,并在其中使用另一个异步管道。

问题是我的第二个异步管道返回null,所以什么也没打印。但是我的第一个异步管道确实运行良好。

那么我该如何在HTML模板中打印zone.title?我只能使用doSomething(id)方法来获得它。

template.component.html

<div *ngFor="let site of sites$ | async">
  <p>{{site.title}}</p>
  <div *ngIf="doSomething(site.id) | async as zone">
     <p>{{zone?.title}}<p>
  </div>
</div>

template.component.ts

public sites$: Observable<{id: string, title: string}[]>;

constructor(private siteService: SiteService) {}

ngOnInit() {
  this.sites$ = this.siteService.getSites();
}

doSomething(id: string): Observable<{id: string, title: string}> {
  return this.siteService.getZoneById(id);
}

site.service.ts

constructor(private http: HttpClient) {}

getSites(): Observable<{id: string, title: string}[]> {
  this.http.get(...);
}

getZoneById(id: string): Observable<{id: string, title: string}> {
  this.http.get(...);
}

1 个答案:

答案 0 :(得分:1)

在模板中调用函数通常不是一个好主意,因为它会导致无法预测的结果。

因此您可以重构代码:

template.component.html

<div *ngFor="let site of sites$ | async">
  <p>{{site.title}}</p>
  <div *ngIf="site.zone$ | async as zone">
     <p>{{zone?.title}}<p>
  </div>
</div>

template.component.ts

public sites$: Observable<{
  id: string,
  title: string,
  zone$: Observable<{id: string, title: string}>
}[]>;

constructor(private siteService: SiteService) {}

ngOnInit() {
  this.sites$ = this.siteService.getSites().pipe(
    map((sites) => {
      return sites.map(site => {
        return {
          id: site.id,
          title: site.title,
          zone$: this.doSomething(site.id),
        };
      })
    })
  );
}

doSomething(id: string): Observable<{id: string, title: string}> {
  return this.siteService.getZoneById(id);
}

检查我的Stackblitz example