【发布时间】:2023-03-13 01:05:02
【问题描述】:
我将解释我在解释使用 Angular 和 RxJS 设计服务的问题之前的上下文。
我有这个模型的一个对象:
{
id: string;
title: string;
items: number[];
}
我通过GET /element/:id获取这个类型的每个对象(称为“元素”)
每个元素都有一个 items: number[],其中包含一个数字数组,每个数字都有一个 URL,所以我为每个数字创建一个新的 GET /element/:id/:itemNumber 并返回项目详细信息。那个项目细节模型是这样的:
{
idItem: string;
title: string;
}
所以在我的服务中,我想为组件提供一个方法,它将返回一个 Observable,它将获得一个对象数组,其中每个对象都有一个元素模型,该元素模型具有一个附加属性,该属性将是其详细信息的数组项目。所以,我将展示我所拥有的:
服务:
getElement(id: string): any {
return this.http.get<Element>(this.basePath + `/element/${id}`).pipe(
map(element => this.getAllItemsDetail(element))
}
getAllItemsDetail(element: Element): any {
return of(...element.items).pipe(
map(val => this.getItemDetail(element.id, val)),
concatAll()
);
}
我的问题是,我不明白如何在 RxJS 中,在 getElement 方法中的 map(element => this.getAllItemsDetail(element)) 之后,合并它返回的 items 数组和我在具有元素对象。我需要在该映射之后添加“任何内容”来计算 Object.Assign 以合并两个对象。
编辑
@chiril.sarajiu 的回答给了我不止一个线索,switchMap 我可以映射 observable(map 用于对象,“使用结果对象进行计算”)。所以我的代码,它不是我所知道的最漂亮的版本......我会尝试它,但它可以工作。所以最终的代码是这样的:
getElement(id: string): any {
return this.http.get<Element>(this.basePath + `/element/${id}`).pipe(
switchMap(element => this.getAllItemsDetail(element)),
map(result => { return Object.assign({}, result.element, {itemsDetail: result.items})})
);
}
getAllItemsDetail(element: Element): any {
const results$ = [];
for (let i = 0; i < element.items.length; i++) {
results$.push(this.getItemDetail(element.id, element.items[i]));
}
return zip(...results$).pipe(
map(items => { return Object.assign({}, { element, items })})
);
}
请注意,如果 results$ 为空,zip 可能不会发出值,在这种情况下,您可以将 of(undefined) 添加到 results$ 数组中,然后考虑到项目将是 [undefined]
【问题讨论】:
标签: javascript angular typescript rxjs