Sum 形式 Array angular 形式的控件

Cli*_*ree 3 reactive-forms angular

我有我的反应形式,看起来像这样

<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>
Run Code Online (Sandbox Code Playgroud)

我想对用户创建的所有行的 itemamt 求和并将它们传递到表单数据中。有人可以帮助我,告诉我如何对表单中的所有 itemamt 字段求和并并排显示用户的总金额是多少?

AJT*_*T82 7

我确实想知道是否有更好的方法,但我尝试使用 getter,它抱怨Expression has changed...尝试添加ChangeDetectorRef到混合中导致无限循环。

所以我决定valueChanges在表单数组中监听,我也需要在其中使用ChangeDetectorRef,所以首先导入它并将它注入到你的构造函数中:

import { ChangeDetectorRef } from '@angular/core';

constructor(private fb: FormBuilder, private ref: ChangeDetectorRef) { }
Run Code Online (Sandbox Code Playgroud)

然后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()
    });
  }) 
Run Code Online (Sandbox Code Playgroud)

为了构建表单,您需要添加一个新的表单控件,因为您希望它成为表单的一部分:

this.invoiceForm = this.fb.group({
  itemRows: this.fb.array([this.initItemRows()])
  summed: [null] // here
}); 
Run Code Online (Sandbox Code Playgroud)

在你的模板中:

<input readonly [ngModel]="summed" formControlName="summed" />
Run Code Online (Sandbox Code Playgroud)

演示


编辑:

我建议你使用我们的好yurzui建议的解决方案,比我的解决方案优雅得多,所以在里面valueChanges使用reduce()

resolvedPromise.then(() => {
  this.summed = values.reduce((acc, cur) => acc + cur.itemamt, 0);
});
Run Code Online (Sandbox Code Playgroud)

和变量:

const resolvedPromise = Promise.resolve(null);
Run Code Online (Sandbox Code Playgroud)

  • 我会使用值来计算总和 http://plnkr.co/edit/Xm0LduSK7GEYCg3n3HV1?p=preview 并且你在每次迭代时调用detectChanges (3认同)