角度2:无法在反应式表单中将表单组添加到表单数组 [英] Angular 2: Can't add form group to form array in reactive Forms

查看:91
本文介绍了角度2:无法在反应式表单中将表单组添加到表单数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建动态表单,并希望动态"添加表单组.

I'm building dynamic form and want to add form groups 'on the fly'.

这是我的几乎可以运行的代码:

Here is my code which almost works:

import {Component, OnInit} from '@angular/core';
import {FormGroup, FormBuilder, FormArray, Validators, FormControl} from "@angular/forms";

export class CombinedComponent implements OnInit {

    ltsForm: FormGroup;

    constructor(private formBuilder: FormBuilder) {
    }

    ngOnInit() {
        this.ltsForm = this.initFormGroup();

        // init products
        for (let i = 0; i < 3; i++) { // add dynamically products
            this.addProduct();
        }

        console.log(this.ltsForm); // Array 'prods' is empty
    }

    // initialize form group, but don't add products yet because they will be added dynamically later
    initFormGroup() {
        let group = this.formBuilder.group({
            products: this.initProductGroup()
        });

        return group;
    }

    initProductGroup() {
        let group = this.formBuilder.group(
            {
                //initialize empty formbuilder array
                prods: this.formBuilder.array([])
            }
        );

        return group;
    }

    initProducts() {
        return this.formBuilder.group({
            id: [''],
            value: false, // checkbox value
        });
    }

    addProduct() {
        <FormArray>this.ltsForm.controls['products'].value.prods.push(this.initProducts());

        console.log(this.ltsForm); // Array 'prods' contains 3 FormGroup elements
    }
} 

模板:

<form [formGroup]="ltsForm"
      novalidate
      (ngSubmit)="save(ltsForm)">

    <div formGroupName="products">
        <div formArrayName="prods">

            <div *ngFor="let product of ltsForm.controls.products.value.prods.controls; let i = index">
                <div [formGroupName]="i">
                    <input type="checkbox"
                           formControlName="value"
                           id="product_{{ i }}"
                           name="product_{{ i }}">
                </div>
            </div>

        </div>
    </div>

    <button type="submit"
            [disabled]="!ltsForm.valid">
        Submit
    </button>
</form>

在方法addProduct()中,我将整个FormGroup元素推到'prods'数组中.因此,最后,ngOnInit()中控制台的输出只包含一个空的"prods"数组,而addProduct()方法中控制台输出的数组包含3个元素.看起来像this.ltsForm失去了它的引用,并且没有更新.有什么想法吗?

In method addProduct() I push the whole FormGroup element to the 'prods' array. So at the end the output from console in ngOnInit() contains just an empty 'prods' array, while the array from console output in addProduct() method has 3 elements. It looks like this.ltsForm looses its reference and isn't updating. Any ideas?

UPD:刚发现,如果我从模板中删除全部内容,则会得到充满数据的产品".

UPD: Just found out that if I remove the whole content from template, I get the 'prods' filled with data.

推荐答案

存在许多小错误和复杂性,因此我缩减了示例并进行了备份. Angular团队有一个嵌套表单数组 plnkr ):

There were a number of small mistakes and complexities, so I pared down your example and built it back up. The Angular team had examples of a nested form array and nested form group that were very helpful. Here was the process (and plnkr):

  1. 有一个简单组:{ projects: '' }.
  2. 为具有一组控件的工作:{ projects: ['a', 'b', 'c'] }.我跳过了prods,这似乎是不必要的.

  1. Got a simple group working: { projects: '' }.
  2. Got a group with an array of controls working: { projects: ['a', 'b', 'c'] }. I skipped prods, it seemed unnecessary.

<form [formGroup]="ltsForm" novalidate (ngSubmit)="save()">
  <div formArrayName="products">
    <div *ngFor="let p of products.controls; let i=index">
      <input [formControlName]="i">
    </div>
  </div>
  <button type="submit" [disabled]="!ltsForm.valid">
    Submit
  </button>
</form>

...

export class CombinedComponent implements OnInit {

  ltsForm: FormGroup;

  get products() { return this.ltsForm.get('products'); }

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
      this.ltsForm = this.formBuilder.group({
        products: this.formBuilder.array([])
      });

      for (let i = 0; i < 3; ++i) {
        this.addProduct();
      }
  }

  addProduct() {
    this.products.push(this.formBuilder.control(''));
  }

  save() {
    console.log(this.ltsForm.value);
  }
} 

  • 最后一步将阵列中的控件替换为组:

    @Component({
      selector: 'combined-component',
      template: `
        <form [formGroup]="ltsForm" novalidate (ngSubmit)="save()">
          <div formArrayName="products">
            <div *ngFor="let p of products.controls; let i=index">
              <div [formGroupName]="i">
                <input formControlName="id">
                <input type="checkbox" formControlName="value">
              </div>
            </div>
          </div>
          <button type="submit" [disabled]="!ltsForm.valid">
              Submit
          </button>
        </form>
      `
    })
    export class CombinedComponent implements OnInit {
    
      ltsForm: FormGroup;
    
      get products() { return this.ltsForm.get('products'); }
    
      constructor(private formBuilder: FormBuilder) {}
    
      ngOnInit() {
          this.ltsForm = this.formBuilder.group({
            products: this.formBuilder.array([])
          });
    
          for (let i = 0; i < 3; ++i) {
            this.addProduct();
          }
      }
    
      addProduct() {
        this.products.push(this.formBuilder.group({
          id: '',
          value: false
        }));
      }
    
      save() {
        console.log(this.ltsForm.value);
      }
    } 
    

  • 这篇关于角度2:无法在反应式表单中将表单组添加到表单数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆