角度模板中的Reduce函数



是否可以在Angular的HTML中执行reduce函数?我在下面确实这样做了,但它会输出解析错误。

HTML

<div *ngIf="report$ | async as report">
<p>
{{ report?.payrolls?.reduce((prev, curr) => (prev.gross - prev.c_a - prev.statutory = prev.charges) + (curr.gross - curr.c_a - curr.statutory = curr.charges), 0) | number }}
</p>
</div>

TS

@Select(ReportState.getEmployeePayslip) report$: Observable<EmployeePayslip>;

您可以直接在模板中使用reduce函数。但您不能定义一个新的lambda,包括传递给reduce函数的lambda。

所以这是有效的:

report?.payrolls?.reduce(accPayloads, 0)

但事实并非如此:

report?.payrolls?.reduce((a, b) => a + b, 0)

这个问题的答案很好地解释了你为什么不能这么做。此外,我强烈建议您不要这样做,因为angular需要在每个更改检测周期中运行这些功能,这可能会导致性能问题。其他答案中已经提到了替代方案,但总的来说,最好是反应性地计算你的值,或者使用管道,它会记住计算结果。

在您的情况下,提到第三种解决方案可能也是一个好主意:创建一个为您进行计算的NGXS选择器,并在组件中使用该选择器。

NGXS状态
@Selector([ReportState.getEmployeePayslip])
public static progress(report: EmployeePayslip): number {
return report.payrolls?
.reduce((prev, curr) => (prev.gross - prev.c_a - prev.statutory = prev.charges) + (curr.gross - curr.c_a - curr.statutory = curr.charges), 0);
}
组件TS
@Select(ReportState.getEmployeePayslipTotal) payslipTotal$: Observable<number>;
HTML
<div *ngIf="payslipTotal$ | async as payslipTotal">
<p> {{ payslipTotal | number }} </p>
</div>

您不能在模板中定义函数。不过,您可以使用组件文件中定义的函数,但在进行更改检测时,这不是一个好方法。这里有很好的解释:https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496

我推荐两个选项:

1.创建第二个可观察对象,它依赖于第一个,也可以通过模板中的async管道访问

this.payrollSummary$: Observable<number> = this.report$.pipe(
map(report => report?.payrolls?.reduce(/*...*/)),
);

2.使用自定义模板管道发送值

<p>{{ report | payrollSummary }}</p>
@Pipe({
name: 'payrollSummary',
})
export class PayrollSummaryPipe implements PipeTransform {
transform(report: EmployeePayslip): number {
return report?.payrolls?.reduce(/*...*/);
}
}

最新更新