我试图在我的角度分量中显示一个可观察的总数,
total$ | async
它应该是购物篮中所有行的计算总和:
totalAmount = sum of (price * unitsOrdered)
我的界面是:
export interface IBasketLine {
unitsOrdered?: number;
price?: number;
}
export interface IBasket {
header?: IBasketHeader;
lines?: Array<IBasketLine>;
}
我的Angular组件包含 2个可观察对象:
basket$: Observable<IBasket>;
nettoTotal$: Observable<number>;
可观察的篮子$是从我的ngrx商店初始化的,所有行在我的视图中都是可见的。这是我的 ngOnInit 函数:
ngOnInit(): void {
this.store.dispatch(new basketActions.Load());
this.basket$ = this.store.pipe(
select(fromBasket.getBasket)
);
this.nettoTotal$ = this.basket$.pipe(
map((basket) => basket.lines),
reduce( ??? )
);
}
如何使用reduce函数,以便在视图中获得正确的总数?
更新:
这确实起作用:
this.nettoTotal$ = this.basket$.pipe(
map((basket) => {
if (basket) {
return basket.lines;
} else {
return [];
}
}),
map((lines) => {
let total = 0;
for (const line of lines) {
const val = Math.round((line.bestelaantal * line.nettoprijs * 100) / 100);
total = total + val;
}
return total;
})
);
更新2:
当我直接调用服务的方法并返回Observable的IBasket时,此代码有效:
this.nettoTotal$ = this.basketService.getBasket().pipe(
map((basket) => basket.lines),
map((lines) => lines.map((line) => line.nettoprijs * line.bestelaantal).reduce(
(accumulator, linePrice) => accumulator + linePrice,
0
))
);
当我使用来自商店的可观察物时,此代码不起作用:
this.nettoTotal$ = this.basket$.pipe(
map((basket) => basket.lines),
map((lines) => lines.map((line) => line.nettoprijs * line.bestelaantal).reduce(
(accumulator, linePrice) => accumulator + linePrice,
0
))
);
答案 0 :(得分:0)
RxJs的reduce
函数的作用类似于Array.prototype.reduce
函数。您为它提供了一个处理reduce和seed值的函数,当Observable
完成时,该reduced值将从流中发出。这是您计算总和的方法:
this.nettoTotal$ = this.basket$.pipe(
map((basket) => basket.lines),
reduce((total, count) => total + count, 0)
);
答案 1 :(得分:0)
由于您的map
返回行,并且每行将包含unitsOrdered
和price
,因此您可以引入另一轮map
并直接返回{{1} } * price
,然后在unitsOrdered
运算符中进行累加。
尝试一下:
reduce
这是您推荐的Sample StackBlitz。
答案 2 :(得分:0)
我终于亲自找到了问题。它完全与reduce运算符无关。目前,我执行了reduce函数,该篮子的数据尚未从后端获取。换句话说,商店尚未从我的LoadSuccess操作接收数据。
因此,我最终在我的减速器中添加了一个新的选择器来计算netTotal。
export const getNetTotal = createSelector(
getBasketFeatureState,
(state) => {
if (!state.basket) {
return 0;
}
let total = state.basket.lines.map((line) => (line.amountOrdered * line.price)).reduce(
(total, amount) => total + amount,
0
);
total = Math.round(total * 100) / 100;
return total;
}
);
ngOnInit函数现在看起来像这样,一切正常:
this.store.dispatch(new basketActions.Load());
this.basket$ = this.store.pipe(select(fromBasket.getBasket));
this.nettoTotal$ = this.store.pipe(select(fromBasket.getNetTotal));