【发布时间】:2018-01-02 18:12:22
【问题描述】:
假设我有一个 Web 服务,它将返回如下基本数据(结果名为 CustomerGroups):
{
0: {
Name: 'Group 1',
Customers: {
0: {
CustomerNo: 1,
Name: 'Customer 1'
},
1: {
CustomerNo: 2,
Name: 'Customer 2'
}
}
},
1: {
Name: 'Group 2',
Customers: {
0: {
CustomerNo: 3,
Name: 'Customer 3'
},
1: {
CustomerNo: 4,
Name: 'Customer 4'
}
}
}
}
此外,我还有一个可以返回详细客户数据的网络服务:
{
CustomerNo: 1,
Street: 'Test Street 123',
PostCode: '99999',
City: 'Blabla',
...
}
我想要做的是在 Angular4 可注入服务中使用 forkJoin 组合这两个服务的结果。但是当我尝试请求给定客户的每个详细信息时,我卡住了:
ReadAll(useCache?: boolean): Observable<ICustomerGroup[]> {
if (!this.customerGroupCache || !useCache) {
return this.http.get(this.urlGetAll)
.map((res: Response) => res.json())
.flatMap((customerGroups: any[]) => {
if (customerGroups.length > 0) {
return Observable.forkJoin(
customerGroups.map((customerGroup: any) => {
return this.customerService.get(/* any CustomerNo of customerGroup.Customers */)
// ^---- This is my problem!!!
})
);
}
// No data! Return empty array
return Observable.of([]);
})
.catch((error: any) => Observable.throw(error.message || 'Server error'));
}
return Observable.of(this.customerGroupCache);
}
如何使用forkJoin 循环每个CustomerGroup(flatMap 曾经这样做)并获取每个Customer 的详细信息?是否可以在forkJoin 中使用forEach?
forkJoin 的结果应如下所示:
{
0: {
Name: 'Group 1',
Customers: {
0: {
CustomerNo: 1,
Name: 'Customer 1',
Street: 'Test Street 123',
PostCode: '99999',
City: 'Blabla'
},
1: {
CustomerNo: 2,
Name: 'Customer 2',
Street: 'Test Street 456',
PostCode: '888',
City: 'Blabla'
}
}
}
...
}
解决方案
根据 taras-d 的描述,我错过了合并多个 Observable 的结果的 mergeMap。我的最终来源如下:
ReadAll(useCache?: boolean): Observable<ICustomerGroup[]> {
if (!this.customerGroupCache || !useCache) {
return this.http.get(this.urlGetAll)
.mergeMap((res: Response) => {
const customerObservables = [];
let groups = res.json();
groups.forEach((group, i) => {
group.Customers.forEach((cust, j) => {
customerObservables.push(this.customerService.get(cust.CustomerNo));
});
});
return Observable.forkJoin(customerObservables)
.map(customers => {
this.customerGroupCache = this.buildCustomerGroupArray(groups, customers);
return this.customerGroupCache;
});
});
}
return Observable.of(this.customerGroupCache);
}
把它们放在一起:
private buildCustomerGroupArray(allGroups: any, allCustomers: any): Array<ICustomerGroup> {
let result: Array<ICustomerGroup> = Array<ICustomerGroup>();
allGroups.forEach((group, index) => {
let newGroup = new CustomerGroup();
newGroup.ActionFlag = ActionType.Undefined;
newGroup.Name = group.Name;
newGroup.OldName = group.OldName;
newGroup.CustomerList = Array<ICustomerGroupItem>();
group.Customers.forEach((cust, index2) => {
if (allCustomers.find(p => p.CustomerNo === cust.CustomerNo)) {
let currCust = allCustomers.find(p => p.CustomerNo === cust.CustomerNo);
let newGroupItem: ICustomerGroupItem = new CustomerGroupItem({
ActionFlag: ActionType.Undefined,
CustomerName: currCust.Name,
CustomerNo: currCust.CustomerNo
});
newGroup.CustomerList.push(newGroupItem);
}
});
result.push(newGroup);
});
return result;
}
【问题讨论】:
标签: json angular web-services typescript fork-join