首页 文章

角度反应表单 - 订阅表单数组中的表单控件实例以获取总 Value

提问于
浏览
0

我正在使用Angular Reactive Forms迭代一个值数组,我希望在Form Array之后有一个total字段来更新Form Array控件值的更改 .

样本数据:

primaryData = {
    products: [
      {
        name: 'test-product',
        unmoved: 21,
        moved: 18 
      },
      {
        name: 'another-product',
        unmoved: 18,
        moved: 42
      }
    ]
  }

我正在创建Reactive Form Controls和Array,如下所示:

setPrimaryQuantities() {
    const control = <FormArray>this.primaryForm.controls.quantities;
    this.primaryData.products.forEach(product =>
      control.push(this.fb.group({
        name: [product.name, Validators.required],
        unmoved: [product.unmoved, Validators.required],
        moved: [product.moved, Validators.required]
      }))
    )
  }

  ngOnInit() {
    this.primaryForm = this.fb.group({
      quantities: this.fb.array([]),
      unmovedTotal: '',
      movedTotal: ''
    })
    this.setPrimaryQuantities();
  }

根据Array控件中的更改,让 unmovedTotalmovedTotal Controls更新的最佳方法是什么?这是一个展示我结构的StackBlitz .

1 回答

  • 3

    在我看来,你要找的总数不应该是这种形式 . 它在你的打字稿中没有任何条件就被禁用了,我想不出你直接编辑总数的用例 . 它只是表单中的计算值 .

    也就是说,一个好处是有一个可观察的类型:

    total$: Observable<{ moved: number, unmoved: number }>
    

    要做到这一点,因为你已经使用了反应形式,它非常直接:)

    this.total$ = this.primaryForm.valueChanges.pipe(
      startWith(this.primaryForm.value),
      map(f => f.quantities.reduce(
        (acc, q) =>
        ({
          moved: acc.moved + q.moved,
          unmoved: acc.unmoved + q.unmoved
        }),
        { moved: 0, unmoved: 0 }
      ))
    );
    

    每次表单更改时,您都希望获得新的总计 . 如果要从初始值(表单的值)中生成新值(总计),请使用 map 运算符 .

    在表单上,我们想循环数量并为 movedunmoved 属性生成一个总和 . 所以在这里我们不能使用 map (基本的JS Map ,而不是RXJS中的 Map )因为它会产生一个数组 . 为此,我们可以使用 reduce (再一次来自纯JS,没有RXJS) .

    现在我们已经获得了可观察性,我们只需要将它用于视图中 . 为了避免两个订阅,我们可以使用带有 as 语法的 ngIf

    <tr *ngIf="total$ | async as total">
      <td>Totals</td>
      <td>{{ total.unmoved }}</td>
      <td>{{ total.moved }}</td>
    </tr>
    

    以下是基于您最初的Stackblitz示例的完整示例:

    https://stackblitz.com/edit/angular-kbk3zm?file=src%2Fapp%2Fapp.component.ts

相关问题