如何在Angular/rxjs中加载需要2个API调用的对象

如何在Angular/rxjs中加载需要2个API调用的对象,angular,rxjs,Angular,Rxjs,我用的是角度6 我有以下课程: export class MyItem{ id: string; name: string; gizmo: Gizmo; }; export class Gizmo{ id: string; name: string; color: string; }; 我必须进行两次API调用。 1-获取MyItems数组。 2-获取给定MyItem的gizmo 我试过这个: this.myItemService.get<MyItem[]>

我用的是角度6

我有以下课程:

export class MyItem{
  id: string;
  name: string;
  gizmo: Gizmo;
};

export class Gizmo{
  id: string;
  name: string;
  color: string;
};
我必须进行两次API调用。
1-获取MyItems数组。
2-获取给定MyItem的gizmo

我试过这个:

this.myItemService.get<MyItem[]>(
    new FindParameters({ name: name })
  ).pipe(tap(z => {
    z.forEach(function (item) {
      this.gizmoService.get(item.id)
        .subscribe(z => {
          item.gizmo = z;
        });
    });

  }))
  .subscribe(x => this.totalCount = x.length);
this.myItemService.get(
新的FindParameters({name:name})
).管道(水龙头(z=>{
z、 forEach(功能(项目){
this.gizmoService.get(item.id)
.订阅(z=>{
item.gizmo=z;
});
});
}))
.subscribe(x=>this.totalCount=x.length);
但是gizmoService似乎不在函数的作用域内。(如果我把它拔出来,服务就好了)

那么,如何加载需要两个单独API调用的对象呢?

.subscribe()
调用到
中。subscribe()
是一种反模式,必须不惜一切代价避免。您应该做的是将api调用合并到一个可观察对象中,并使用
.subscribe()
获得最终结果

根据我所看到的,以下是您应该如何将可观察数据转换为gizmo数据的项目数据:

this.myItemService.get<MyItem[]>(
    new FindParameters({ name: name })
).pipe(
    mergeMap((myItems: MyItem[]) => {
        const gizmoRequestArray: Observable<MyItem>[] = myItems.map(item => {
            return this.gizmoService.get(item.id).pipe(
                map(z => {
                    item.gizmo = z;
                    return item;
                })
            );
        });
        return combineLatest(gizmoRequestArray);
    })
)
.subscribe(x => this.totalCount = x.length);
this.myItemService.get(
新的FindParameters({name:name})
).烟斗(
合并映射((myItems:MyItem[])=>{
const gizmoRequestArray:Observable[]=myItems.map(item=>{
返回此.gizmoService.get(item.id).pipe(
地图(z=>{
item.gizmo=z;
退货项目;
})
);
});
返回组合测试(gizmoRequestArray);
})
)
.subscribe(x=>this.totalCount=x.length);

这应该是非常简单的,只是要知道这并不能保持相同的项目顺序

this.myItemService.get<MyItem[]>(...)
  .pipe(
    mergeAll(), // flatten the array into single emission
    mergeMap(item => this.gizmoService.get(item.id).pipe(
      map(gizmo => {
        item.gizmo = gizmo;
        return item;
      })
    )),
    toArray(), // turn all result into an array again
  )
  .subscribe(...)
this.myItemService.get(…)
.烟斗(
mergeAll(),//将阵列展平为单个发射
mergeMap(item=>this.gizmoService.get(item.id).pipe(
映射(gizmo=>{
item.gizmo=gizmo;
退货项目;
})
)),
toArray(),//再次将所有结果转换为数组
)
.订阅(…)

您还可以将
resultSelector
作为
mergeMap
的第二个参数传递。这样,您就可以省去编写嵌套的
。管道
映射
结果选择器不受欢迎。我认为您在嵌套的pipe@OlesSavluk在这种情况下没有。如果我在
mergeMap
之后使用
map
而不是在其内部,那么结果选择器将非常有用。哦,
resultSelector
确实不受欢迎,将在v7中删除。谢谢你指出这一点!