因此,我有一个服务器,它可以根据请求返回对象数组。
示例:
[
{
id: 1
name: name1
},
{
id: 2
name: name2
}
]数组可以有无限个元素;
之后,我必须用响应id为数组中的每个元素发送新的请求。
示例:
https://localhost/api/parent/${id}/child答复:
[
{
childId: 1
name: name1
},
{
childId: 2
name: name2
},
{
childId: 3
name: name3
}
]在此之后,我必须为新请求的每一个响应发送新的请求。
示例:
https://localhost/api/parent/${id}/child/${childId}/grandChild答复:
[
{
grandChildId: 1
name: name1
},
{
grandChildId: 2
name: name2
},
{
grandChildId: 3
name: name3
}
]和其他人的反应是相似的
在那之后,我必须组织数据,使其看起来像这样
[
{
id: 1
name: name1
children: [
{
childId: 1
name: name1,
grandChildren: [
{
grandChildId: 1
name: name1
},
{
grandChildId: 2
name: name2
},
{
grandChildId: 3
name: name3
}
]
},
{
childId: 2
name: name2
},
{
childId: 3
name: name3
}
]
},
{
id: 2
name: name2
}
]每个父类都有一个子数组,每个子元素都有一个grandChildren数组。
这是我的尝试,但如果我尝试在组件中执行parents.forEach(父=> console.log(parent.childern)),则没有定义
getData() {
return this.http.get<Parent[]>(baseUrl + 'parent', {withCredentials: true}).pipe(
map(parents => {
parents.forEach(parent => {
this.getChildren(parent).subscribe(Children => {
parent.Children = Children;
parent.Children.forEach(Children => {
this.getGrandChildren(Children).subscribe(grandChild => {
Children.grandChildren = grandChild;
});
});
});
});
return parents;
})
);}
getChildren(parent: Parent): Observable<Child[]> {
return this.http.get<Children[]>(baseUrl + `parent/${parent.id}/children`, {withCredentials: true});}
getGrandChildren(child: Child): Observable<GrandChild[]> {
return this.http.get<GrandChild[]>(baseUrl + `children/${child.id}/GrandChildren`, {withCredentials: true});}
发布于 2018-11-08 21:23:03
考虑到您的问题,它似乎是递归性质的。
Parent、Child、GrandChild都类似于树的节点和叶子的平面表示形式。如果是这样的话,您可以查看这,了解如何使用RxJS进行递归处理的一些细节。
严格按照你表达问题的方式,至少以我的理解,这里是解决问题的方法。
getParents()
.pipe(
switchMap(parents => from(parents)),
mergeMap(parent => getChildren(parent)
.pipe(
switchMap(children => from(children)),
mergeMap(child => getGrandChildren(child)
.pipe(
tap(grandChildren => child.grandChildren = grandChildren),
map(() => child)
)
),
toArray(),
tap(children => parent.children = children),
map(() => parent)
), 1 // cuncurrency set to 1 to guarantee same order
),
)
.subscribe(d => console.log(JSON.stringify(d, null, 2)))我用下面的模拟数据和函数测试了它
const parents = [
{id: 1, name: 'name1'},
{id: 2, name: 'name2'},
];
const children = [
{childId: 1, name: 'name1'},
{childId: 2, name: 'name2'},
{childId: 3, name: 'name3'},
];
const grandChildren = [
{grandChildId: 1, name: 'name1'},
{grandChildId: 2, name: 'name2'},
{grandChildId: 3, name: 'name3'},
];
function getParents(): Observable<Parent[]> {
return of(parents).pipe(delay(10));
}
function getChildren(parent: Parent): Observable<Child[]> {
return (parent.id === 1 ? of(children) : of([])).pipe(
delay(100)
);
}
function getGrandChildren(child: Child): Observable<GrandChild[]> {
return (child.childId === 1 ? of(grandChildren) : of([])).pipe(delay(1000));
}发布于 2018-11-08 13:58:03
你可以这样做:
getRoot() {
return this.http.get<Parent[]>(baseUrl + 'parent', {withCredentials: true}).pipe(
switchMap(items => forkJoin(items.map(i => this.getChild(i))))
)
}
getChild(parent) {
return this.http.get<Children[]>(baseUrl + `parent/${parent.id}/children`, {withCredentials: true}).pipe(
switchMap(items => forkJoin(items.map(i => this.getGrandChild(i)))),
map(resp => (parent.children = resp, parent))
);
}
getGrandChild(parent) {
return this.http.get<GrandChild[]>(baseUrl + `children/${child.id}/GrandChildren`, {withCredentials: true}).pipe(
map(resp => (parent.grandChildren = resp, parent))
)
}使用items.map将结果数组转换为相关子请求的数组。
然后,它使用forkJoin将所有这些请求连接到一个可观察的
然后使用switchMap发出请求,使用map将子级添加到响应中。
发布于 2018-11-08 13:17:42
你有可能混淆大写和小写吗?使用约定能够识别某物。
好吧,试试parent.children
https://stackoverflow.com/questions/53208261
复制相似问题