Angular Reactive Form - 订阅表单数组中的表单控件实例以获得总值

Posted

技术标签:

【中文标题】Angular Reactive Form - 订阅表单数组中的表单控件实例以获得总值【英文标题】:Angular Reactive Form - Subscribe to instances of Form Control in Form Array to get total value 【发布时间】:2018-10-31 10:23:39 【问题描述】:

我正在使用 Angular Reactive Forms 遍历一个值数组,我希望在 Form Array 之后有一个总字段,用于更新 Form Array 控件值的更改。

样本数据:

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

我正在创建响应式表单控件和数组,如下所示:

  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();
  

让我的unmovedTotalmovedTotal 控件根据数组控件中的更改进行更新的最佳方式是什么。这是一个 StackBlitz 展示我的结构。

【问题讨论】:

【参考方案1】:

在我看来,您要查找的总数不应该是这种形式。它在您的 Typescript 中没有任何条件地被禁用,我想不出您可以直接编辑总数的用例。它只是一个计算出来的值。

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

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 映射,而不是来自 RXJS 的映射),因为它会生成一个数组。为此,我们可以使用reduce(再次来自纯JS,这里没有RXJS)。

现在我们已经有了 observable,我们只需要在视图中使用它。为了避免两次订阅,我们可以使用 ngIfas 语法:

<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

【讨论】:

以上是关于Angular Reactive Form - 订阅表单数组中的表单控件实例以获得总值的主要内容,如果未能解决你的问题,请参考以下文章

Angular Reactive Form 中的 DOB 验证

Angular Reactive Form 的一个具体使用例子

typescript 使用FormBuilder和AngularMaterial的Angular - Reactive Form

Angular Reactive Form:无法设置未定义的属性

Angular Reactive Form 如何存储 JSON 数据?

如何创建您的第一个 Angular Reactive Form