Javascript 使用另一个可观察项修改可观察项,并返回初始可观察项

Javascript 使用另一个可观察项修改可观察项,并返回初始可观察项,javascript,angular,rxjs,observable,Javascript,Angular,Rxjs,Observable,我想返回带有加载图像的ClientDetails对象 因此,检索一个可观测值,并用另一个可观测值修改该值,然后返回整个可观测值 我希望下面的代码说明了我要做的事情,但我知道使用RxJS操作符可以更干净地完成。有人知道怎么做吗 interface ClientDetails { team: Member[]; } interface Member { id: number; image: string; } this.clientDetails$ = this.client

我想返回带有加载图像的ClientDetails对象

因此,检索一个可观测值,并用另一个可观测值修改该值,然后返回整个可观测值

我希望下面的代码说明了我要做的事情,但我知道使用RxJS操作符可以更干净地完成。有人知道怎么做吗

interface ClientDetails {
   team: Member[];
}

interface Member {
   id: number;
   image: string;
}


this.clientDetails$ = this.clientService.getClientDetails().subscribe((details: ClientDetails) => {
   details.team.forEach(member => {
      this.imageService.getImage(member.id).subscribe((image: string) => {
         member.image = image
      }
   }
}

你认为RxJS操作符会使它更优雅是对的。目前,变量this.clientDetails$不具有可观察性,也不能像您所期望的那样工作

相反,您可以使用高阶映射操作符
switchMap
从一个可观察对象切换到另一个(通常最好避免嵌套订阅)和
forkJoin
函数并行触发多个可观察对象。您还可以使用JS destructing和RxJS
map
操作符返回对象及其所有内容

试试下面的方法

this.clientDetails$=this.clientService.getClientDetails().pipe(
switchMap((详细信息:ClientDetails)=>
分叉连接(
details.team.map(成员=>
this.imageService.getImage(member.id).pipe(
映射(image:string=>({…member,member.image:image}))
)
)
).烟斗(
map((团队:任意)=>({…详细信息,详细信息。团队:团队}))
)
);
);

注意:我没有测试代码。请检查返回的对象是否是您实际需要的对象。

您认为RxJS操作符会使其更优雅是正确的。目前,变量this.clientDetails$不具有可观察性,也不能像您所期望的那样工作

相反,您可以使用高阶映射操作符
switchMap
从一个可观察对象切换到另一个(通常最好避免嵌套订阅)和
forkJoin
函数并行触发多个可观察对象。您还可以使用JS destructing和RxJS
map
操作符返回对象及其所有内容

试试下面的方法

this.clientDetails$=this.clientService.getClientDetails().pipe(
switchMap((详细信息:ClientDetails)=>
分叉连接(
details.team.map(成员=>
this.imageService.getImage(member.id).pipe(
映射(image:string=>({…member,member.image:image}))
)
)
).烟斗(
map((团队:任意)=>({…详细信息,详细信息。团队:团队}))
)
);
);
注意:我没有测试代码。请检查返回的对象是否是您实际需要的对象。

请重试

this.clientDetails$ = this.clientService.getClientDetails().pipe(
  switchMap((details: ClientDetails) => {
    const images$: Observable<string[]> = forkJoin(
     details.team.map(member => this.imageService.getImage(member.id))
    );

    return forkJoin([of(details), images$]);
  }),
  map(([details, images]) => {
    return {
      team: _.zipWith(details.team, images, (d, m) => d.image = m) // zipWith = lodash function
    };
  }),
).subscribe((details: ClientDetails) => console.log(details));
this.clientDetails$=this.clientService.getClientDetails().pipe(
switchMap((详细信息:ClientDetails)=>{
常量图像$:可观察=forkJoin(
details.team.map(member=>this.imageService.getImage(member.id))
);
返回forkJoin([of(详细信息),images$]);
}),
地图(([详细信息,图像])=>{
返回{
team:u.zipWith(details.team,images,(d,m)=>d.image=m)//zipWith=lodash函数
};
}),
).subscribe((细节:ClientDetails)=>console.log(细节));
试试看

this.clientDetails$=this.clientService.getClientDetails().pipe(
switchMap((详细信息:ClientDetails)=>{
常量图像$:可观察=forkJoin(
details.team.map(member=>this.imageService.getImage(member.id))
);
返回forkJoin([of(详细信息),images$]);
}),
地图(([详细信息,图像])=>{
返回{
team:u.zipWith(details.team,images,(d,m)=>d.image=m)//zipWith=lodash函数
};
}),
).subscribe((细节:ClientDetails)=>console.log(细节));

您自己试过吗?提示:您可能需要使用
merge
switchMap
1)请在问题中发布任何代码更新。要阅读注释中的代码几乎是不可能的。2) 此代码中的属性名称与原始问题不同。问题中没有
这个。_client
参数和属性
personId
。最好保持代码的一致性。这样可以避免你和试图回答这个问题的人感到困惑。你自己试过什么吗?提示:您可能需要使用
merge
switchMap
1)请在问题中发布任何代码更新。要阅读注释中的代码几乎是不可能的。2) 此代码中的属性名称与原始问题不同。问题中没有
这个。_client
参数和属性
personId
。最好保持代码的一致性。这样可以避免你和试图回答这个问题的人都感到困惑。这样不行。从图像到成员的管道和映射(第4行和第5行)应位于this.imageService.getImage observable上,否则成员在将图像映射到成员+图像时超出范围。不管怎么说,总的原则是正确的,一旦确定了,就会很好地工作。谢谢你的好球。一定是急着错误地将管道连接到
数组#map
。我已经编辑了答案。谢谢,这样不行。从图像到成员的管道和映射(第4行和第5行)应位于this.imageService.getImage observable上,否则成员在将图像映射到成员+图像时超出范围。不管怎么说,总的原则是正确的,一旦确定了,就会很好地工作。谢谢你的好球。一定是急着错误地将管道连接到
数组#map
。我已经编辑了答案。谢谢