我的反应形式看起来像这样
<form [formGroup]="addInvoiceForm" (submit)="onAddInvoiceFormSubmit()">
<div [formArrayName]="itemRows">
<div *ngFor="let itemrow of addInvoiceForm.controls.itemRows.controls; let i=index" [formGroupName]="i">
<input autocomplete="off" type="text" formControlName="itemqty">
<input autocomplete="off" type="text" formControlName="itemrate">
<!-- the input field below is to be summed -->
<input autocomplete="off" type="text" formControlName="itemamt" [ngModel]="itemrow.get('itemqty').value * itemrow.get('itemrate').value">
</div>
</div>
<button type="button" (click)="addItemRow()">Add New Row</button>
</form>
我想总结用户创建的所有行的itemamt并将它们传递给表单数据。有人可以帮助我,告诉我如何将表格中的所有itemamt字段相加并并排显示用户的总金额是什么?
答案 0 :(得分:4)
我想知道是否有更好的方法,但我尝试使用getter,抱怨Expression has changed...
尝试将ChangeDetectorRef
添加到混音中会导致无限循环。
所以我决定在表单数组中监听valueChanges
,我还需要使用ChangeDetectorRef
,所以首先导入它并将其注入构造函数中:
import { ChangeDetectorRef } from '@angular/core';
constructor(private fb: FormBuilder, private ref: ChangeDetectorRef) { }
然后是valueChanges
:
// subscribe to changes in the formArray
this.invoiceForm.get('itemRows').valueChanges.subscribe(values => {
// reset the total amount
this.summed = 0;
const ctrl = <FormArray>this.invoiceForm.controls['itemRows'];
// iterate each object in the form array
ctrl.controls.forEach(x => {
// get the itemmt value and need to parse the input to number
let parsed = parseInt(x.get('itemamt').value)
// add to total
this.summed += parsed
this.ref.detectChanges()
});
})
要构建表单,您需要添加一个新的表单控件,因为您希望它将成为表单的一部分:
this.invoiceForm = this.fb.group({
itemRows: this.fb.array([this.initItemRows()])
summed: [null] // here
});
在你的模板中:
<input readonly [ngModel]="summed" formControlName="summed" />
我建议您使用我们的优质yurzui建议的解决方案,比我的解决方案更优雅,因此在valueChanges
内使用reduce()
resolvedPromise.then(() => {
this.summed = values.reduce((acc, cur) => acc + cur.itemamt, 0);
});
和变量:
const resolvedPromise = Promise.resolve(null);
答案 1 :(得分:0)
求和逻辑在组件类中最好,而不是在HTML中。您可以使用返回总和的getter定义属性。
一般来说,语法是这样的:
get sum():number {
let summed = 0;
for (var key in sample) {
summed += sample[key];
};
return summed;
}
注意:您也可以使用Array.prototype.reduce(),但上面的语法更直接。
另外,请考虑使用ngSubmit而不是提交。
答案 2 :(得分:0)
如果你想在提交帖子请求之前加总所有值,你可以这样做。
在提交请求中传递表单值
<form [formGroup]="addInvoiceForm" novalidate (submit)="onAddInvoiceFormSubmit(addInvoiceForm.value)">
</form>
在组件文件中。
您将更新表单对象。只需迭代addInvoiceForm.itemRows并创建sum。
onAddInvoiceFormSubmit(addInvoiceForm){
// you will have update form object. just iterate the addInvoiceForm.itemRows and create sum.
}
注意: - 在启用提交按钮
之前执行所有验证答案 3 :(得分:0)
yurzui建议的答案
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
const resolvedPromise = Promise.resolve(null);
@Component({
selector: 'my-app',
template: ...
})
export class App implements OnInit {
public invoiceForm: FormGroup;
summed: number;
constructor(private fb: FormBuilder, private ref: ChangeDetectorRef) {}
ngOnInit(){
this.invoiceForm = this.fb.group({
itemRows: this.fb.array([this.initItemRows(), this.initItemRows()])
});
this.invoiceForm.get('itemRows').valueChanges.subscribe(values => {
resolvedPromise.then(() => {
this.summed = values.reduce((acc, cur) => acc + cur.itemamt, 0);
});
})
}
}