【问题标题】:How to pass parameters while using the async pipe in Angular/rxjs?在 Angular/rxjs 中使用异步管道时如何传递参数?
【发布时间】:2021-12-17 20:16:03
【问题描述】:

我正在尝试在 Angular 中使用声明性方法,使用 async 管道解开可观察对象并使用 OnPush 更改检测。

我有第二个 observable,它可能会或可能不会被调用,并且需要来自第一个 observable 的数据才能完成。

order.component.html

<div *ngIf="order$ | async as order">
    <h3> Order {{ order.id }} </h3>
    ....
     
    <app-returns *ngIf="order.status === 'Returned'"
        [rma]="rma$ | async" >
    </app-returns>

</div>

order.component.ts

order$: Observable<Order> = this.route.paramMap.pipe(
   map((params: ParmaMap) => +params.get('id')),
   switchMap((id: number) => 
       this.orderSvc.get(id)
));

rma$: Observable<Rma> = this.order$.pipe(
    switchMap((order: Order) => 
        this.rmaSvc.get(order.rma.id)
));

这种方法的问题是订单服务对 API 进行了两次调用来完成此操作。

当我在模板中需要多个 observable 时,我通常会使用 forkJoincombineLatest 来组合它们。但在这种情况下,我只想在必要时调用 rma 服务。

其他更天真的方法(虽然很好地说明了问题)会产生有趣的结果。你能说 429 吗?

 <app-returns *ngIf="order.status === 'Returned'"
    [rma]="rma$(order.rma.id) | async" >
 </app-returns>

打字稿

rma$(id: number): Observable<Rma> {
    return this.rmaSvc.get(id);
}

如何在使用异步管道时传递参数?

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    您可以使用 shareReplay 将您的订单 observable 更改为:

    order$: Observable<Order> = this.route.paramMap.pipe(
       map((params: ParmaMap) => +params.get('id')),
       switchMap((id: number) => 
           this.orderSvc.get(id)
       ),
       shareReplay(1)
    );
    

    然后使用 switchMap 创建你的 rma observable

    rma$: Observable<Rma> = order$.pipe(
      switchMap((order: Order) => 
        this.rmaSvc.get(order.rma.id)
    )
    

    【讨论】:

    • 适合账单干净的声明式方法,并且只访问 API 一次。谢谢!
    猜你喜欢
    • 2020-03-26
    • 2020-09-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-26
    相关资源
    最近更新 更多