问题描述
我是 rxjs 新手。
我正在尝试组合多个 observable 以从 rest api 获取数据列表并加载到 ngx 数据表中
在 server-side paging on ngx-datatable example 之后,我定义了一个 PageData 对象:
export class PagedData<T> {
data = new Array<T>();
page = new Page();
}
并且我的组件中有一个有效的 setPage 方法来检索我的用户列表:
setPage(pageInfo) {
this.page.pageNumber = pageInfo.offset;
this.pageObserver = this.userService.getPaged<User>(this.page).subscribe(pagedData => {
this.page = pagedData.page;
this.rows = pagedData.data;
});
}
现在我必须用其他一些逻辑来改进这个解决方案。 我的其余服务器中的 User 对象具有以下形式:
{
"createdAt": "2021-02-20T13:06:23.911Z","firstname": "Roberto","id": 7,"lastname": "Rossetti","links": [
{
"saleforces": "/users/7/saleforces"
}
],"name": "robertorossetti","parent": null,"parentId": null,"updatedAt": "2021-02-20T13:06:23.933Z","users": []
}
所以我需要点击链接“/users/7/saleforces”来检索与我的用户相关的 saleforces。 我被困在这里了。
我尝试实现一个新的 observable,以这种方式扩展我的工作代码,遵循我发现的示例 here
public getPagedWithSaleForce2(page: Page,queryParams?: querystringparameters,options?: HttpOptions): Observable<PagedData<User>> {
return super.getPaged<User>(page,queryParams,options).pipe(
switchMap((pagedData: PagedData<User>) => {
if (pagedData.data.length > 0) {
return forkJoin(
pagedData.data.map((user: User) => {
const saleForceEndpoint = _.find(user.links,'saleforces');
return this.getRaw<SaleForce>(saleForceEndpoint.saleforces).pipe(
map((saleForce: SaleForce[]) => {
user.saleForces = saleForce;
return (user);
})
);
})
);
} else {
return of(null);
}
})
);
}
显然这段代码不起作用。
那么,我如何用通过销售队伍丰富的用户数组来填充我的 pageData.data? 如何并行调用 saleForceEndpoint?
在此先感谢您的帮助
解决方法
我找到了一个将问题一分为二的解决方案:
在我的控制器中:
# user-list.component.ts
setPage(pageInfo) {
this.page.pageNumber = pageInfo.offset;
this.pageObserver = this.userService.getPagedWithSaleForce(this.page).subscribe(pagedData => {
this.page = pagedData.page;
this.rows = pagedData.data;
});
}
在我的服务中:
# user.service.ts
public getPagedWithSaleForce(page: Page,queryParams?: QueryStringParameters,options?: HttpOptions): Observable<PagedData<User>> {
return super.getPaged<User>(page,queryParams,options)
.pipe(
mergeMap((pagedData: PagedData<User>) => {
return this.followSaleforceLink(pagedData).pipe(
map(users => {
return {users,pagedData};
})
);
}),map(({users,pagedData}) => {
pagedData.data = users;
return pagedData;
})
);
}
public followSaleforceLink(pagedData: PagedData<User>): Observable<User[]> {
return forkJoin(
pagedData.data.map((user: User) => {
const saleForceEndpoint = _.find(user.links,'saleforces');
return this.getRaw<SaleForce>(saleForceEndpoint.saleforces).pipe(
map((saleForce: SaleForce[]) => {
user.saleForces = saleForce;
return user;
})
);
})
);
}