【问题标题】:How to load additional data for a collection with rxjs如何使用 rxjs 为集合加载附加数据
【发布时间】:2020-07-10 02:42:21
【问题描述】:
我正在努力理解不同的 rxjs 运算符。例如,当我有一组对象并且我想从 api 向每个对象添加其他数据时。
例如
people = [{id: 1, name: null}, {id:2, name: null}]
from(people).pipe(
map(person => {
return api.getName(person.id).pipe(
map(name => person.name = name)
)
})
).subscribe(people =>
console.log(people) // should be [{id: 1, name: bob}, {id:2, name: alice}]
)
我尝试使用不同变体的mergeMap、map、switchMap,但我从来没有弄清楚如何将附加数据映射到数组中。
【问题讨论】:
标签:
javascript
angular
rxjs
【解决方案1】:
您的问题很可能是当您使用地图/切换地图时,您正在返回分配的结果person.name = name;
当你像这样使用没有大括号的箭头函数时
() => something;
其实是简写
() => {
return something
}
这是一个工作示例,创建了一些草率的类以使其工作...
https://stackblitz.com/edit/angular-ivy-xfunnc?file=src%2Fapp%2Fapp.component.ts
people = [{id: 1, name: null}, {id:2, name: null}];
peopleWithNames = from(this.people).pipe(
switchMap(person => {
return this.api.getName(person.id).pipe(
map(name => {
// set the person's name property
person.name = name;
// but return the whole person object, not just the retrun from the assignment
return person;
})
)
})
).subscribe(p => {
console.log(p)
})
【解决方案2】:
如果你想要一个列表,我认为你需要使用 forkJoin。您将人员的每个元素映射到一个电话
people = [{id: 1, name: null}, {id:2, name: null}];
forkJoin(people.map(p=>this.api.getName(person.id))
.subscribe((res:any[])=>{
res.forEach((p:any,index)=>{
people[index]={...people,..p}
})
})
你也可以使用 map 来获取包含完整元素的响应
people = [{id: 1, name: null}, {id:2, name: null}];
forkJoin(this.people.map(p=>this.api.getName(p.id))).pipe(
map((res:any[])=>{
const result=this.people.map((p,index)=>
//if the response is an object map to
//({...p,...res[index]})
//if the response is a string,
({...p,name:res[index]})
)
return result
})
).subscribe(res=>{console.log(res)})