Angular 循环获取可观察数组数据并获取其中的另一个数据数组
Angular Loop on fetched observable array data and fetch another array of data in it
你好,我有一个 API 调用 getItems()
,return 数据如下:
[
{
name: 'item1',
materials: [
1,
2,
3,
],
},
{
name: 'item2',
materials: [
2,
3,
6,
],
}
...
]
另一个 API 调用 getMaterial(id)
return 一个 material 的数据,如下所示:
{
name: 'mat1',
img: '/img.jpg'
}
我想要实现的是使用 materials 数据获取所有项目数据。我设法获得了 material 的所有可观察到的调用,但我不知道之后要做什么。
这就是我到目前为止所做的:
public getAllItemsData(): Observable<any> {
return getItems().pipe(
map((list: items[]) => {
return list.map(item => {
const allMat = item.materials.map(m => getMaterial(m))
return forkJoin(allMat).pipe(
map(data => {
return {
...item,
materials: data
}
})
)
})
}),
);
}
但它不起作用。感谢您的帮助。
试试这个。
使用 switchMap, mergeMap, from, forkJoin
getItems()
.pipe(
switchMap((items) =>
// for each items
from(items).pipe(
// merge map to run parallel for each items
mergeMap(({ materials, ...item }) =>
// wait to retrive all materials details of current item at mergeMap
// after completing use map to map item with retrived materials
forkJoin(
materials.map((m) => this.getMaterial(m))
).pipe(map((materialDetails) => ({ ...item, materials: materialDetails })))
)
)
)
)
.subscribe((result) => {
console.log(result);
});
与上面非常相似,只是管道嵌套较少
interface Item {
name: string;
materials: number[];
}
interface MaterialData {
name: string;
img: string;
}
public getAllItemsData() {
return getItems().pipe(
switchMap((items: Item[]) => from(items)), // use 'from' to deal with one Item at a time
mergeMap(({ materials, name }: Item) =>
forkJoin(materials.map((mat) => getMaterial(mat))) // create array of observables using map, and pass into forkJoin
.pipe(
map((materials) => ({ name, materials })), // reconstruct object
),
),
toArray(), // collect all emissions and output as an array
);
};
我认为您只是缺少最后一个 merge/forkJoin 来订阅您创建的可观察对象数组。
public getAllItemsData(): Observable<any> {
return getItems().pipe(
map((list: items[]) =>
list.map(item =>
forkJoin(
item.materials.map(m => getMaterial(m))
).pipe(
map(materials => ({
...item,
materials
}))
)
)
),
// Subscribe to the list created above
mergeMap((list:Observable<any>[]) => forkJoin(list))
);
}
你好,我有一个 API 调用 getItems()
,return 数据如下:
[
{
name: 'item1',
materials: [
1,
2,
3,
],
},
{
name: 'item2',
materials: [
2,
3,
6,
],
}
...
]
另一个 API 调用 getMaterial(id)
return 一个 material 的数据,如下所示:
{
name: 'mat1',
img: '/img.jpg'
}
我想要实现的是使用 materials 数据获取所有项目数据。我设法获得了 material 的所有可观察到的调用,但我不知道之后要做什么。
这就是我到目前为止所做的:
public getAllItemsData(): Observable<any> {
return getItems().pipe(
map((list: items[]) => {
return list.map(item => {
const allMat = item.materials.map(m => getMaterial(m))
return forkJoin(allMat).pipe(
map(data => {
return {
...item,
materials: data
}
})
)
})
}),
);
}
但它不起作用。感谢您的帮助。
试试这个。 使用 switchMap, mergeMap, from, forkJoin
getItems()
.pipe(
switchMap((items) =>
// for each items
from(items).pipe(
// merge map to run parallel for each items
mergeMap(({ materials, ...item }) =>
// wait to retrive all materials details of current item at mergeMap
// after completing use map to map item with retrived materials
forkJoin(
materials.map((m) => this.getMaterial(m))
).pipe(map((materialDetails) => ({ ...item, materials: materialDetails })))
)
)
)
)
.subscribe((result) => {
console.log(result);
});
与上面非常相似,只是管道嵌套较少
interface Item {
name: string;
materials: number[];
}
interface MaterialData {
name: string;
img: string;
}
public getAllItemsData() {
return getItems().pipe(
switchMap((items: Item[]) => from(items)), // use 'from' to deal with one Item at a time
mergeMap(({ materials, name }: Item) =>
forkJoin(materials.map((mat) => getMaterial(mat))) // create array of observables using map, and pass into forkJoin
.pipe(
map((materials) => ({ name, materials })), // reconstruct object
),
),
toArray(), // collect all emissions and output as an array
);
};
我认为您只是缺少最后一个 merge/forkJoin 来订阅您创建的可观察对象数组。
public getAllItemsData(): Observable<any> {
return getItems().pipe(
map((list: items[]) =>
list.map(item =>
forkJoin(
item.materials.map(m => getMaterial(m))
).pipe(
map(materials => ({
...item,
materials
}))
)
)
),
// Subscribe to the list created above
mergeMap((list:Observable<any>[]) => forkJoin(list))
);
}