Angular和RxJS-合并两个HTTP请求,但立即发出外部请求



我对Angular和RxJS还很陌生,很难理解RxJS运算符的某些方面。我这里有一些代码(在一个组件中(:

this.salesService.getOrders().subscribe(orders => {
this.orders = orders;
this.orders.forEach((order, index) => {
this.salesService.getOrderCustomers(order.id).subscribe(customers => {
this.orders[index]['customerName'] = customers.map(c => {return c.name}).join(", ");
})
});
});

这样做的好处是,当在我的模板中的表中使用this.orders时,它将立即可用,然后随着对getOrderCustomers服务方法的每次调用完成,包含客户名称的列将填充。

我的问题是,如果用纯RxJS也可以表达,因为上面似乎不是";RxJS方式";,我想学习。此外,为了在NgRx ComponentStore中隔离获取客户的效果,我的理解是,上述方法将不起作用,因为effect方法必须返回一个可观察的。

我尝试了一些类似的东西:

this.salesService.getOrders().pipe(
mergeMap(response =>
from(response.orders).pipe(
concatMap((oneOrder: object) => {
return this.salesService.getOrderCustomers(oneOrder['id'])
}),
reduce((customers, customer) => [...customers, customer], []),
map(customerList => {
/*  ?? Here I would return 'response' with the customer name added into each order, 
but I have no indexing of the orders to work with */
})
)
),

我有两个问题——第一,我不知道如何将检索到的客户添加到response.orders变量的正确位置,第二,在完成所有内部请求之前,外部可观察对象似乎不会发出。有没有任何RxJS方法可以从内部可观测逐渐改变外部可观测,同时最初以其原始状态发射外部可观测?

我有一种感觉,我正在以一种错误的、非角度的、非RxJS的方式来处理这个问题。任何意见都将不胜感激。提前谢谢。

用第二个请求中的另一个值扩展数组值的常见问题。

extendedOrders$ = this.salesService.getOrders().pipe(
switchMap(orders => {
return forkJoin(orders.map(order => {
return this.salesService.getOrderCustomers(order.id).pipe(
map(customer => ({ ...order, customerName: customer.name })),
);
}));
}),
);

这里有一个解决方案,它不会对您已经做的事情有太大改变(因此可能更容易理解(:

this.salesService.getOrders().pipe(
mergeMap(orders => 
merge(
orders.map((order, index) => this.salesService.getOrderCustomers(order.id).pipe(
map(customers => customers.map(c => c.name).join(", ")),
map(customers => ({customers, index}))
))
).pipe(
scan((acc, {customers, index}) => {
const ordersSoFar = [...acc];
ordersSoFar[index]['customerName'] = customers;
return ordersSoFar;
}, orders)
)
)
).subscribe(orders => {
this.orders = orders;
});

这里最大的区别是,它不是在后台更新订单,让Angular变化检测发现订单已经改变,而是在每次更新时发出更新的订单。

一开始应该是一样的,但如果你愿意的话,可以直接在模板中使用可观察的内容(不需要自己订阅(。

您有可观察的订单orders$ = this.salesService.getOrders()。用*ngFor="let order of orders$ | async"在表中显示

然后你有功能提取一些额外的订单数据

getCustomers(order: Order): Observable<Customer> {
return /* data from service */
}

然后在组件模板中订阅每个订单的客户数据,并将其呈现为{{ getCustomers(order) | async }}

主要好处是订单数据已经可以呈现,同时可以提取其他数据。当然,这可以优化,客户数据可以缓存等等

并将changeDetection设置为onPush以获得更好的性能。

相关内容

  • 没有找到相关文章

最新更新