113

表单组

FormGroup将每个子 FormControl 的聚合到一个对象中,每个控件名称作为键。

const form = new FormGroup({
  first: new FormControl('Nancy', Validators.minLength(2)),
  last: new FormControl('Drew')
});

表单数组

FormArray将每个子 FormControl 的聚合到一个数组中。

const arr = new FormArray([
  new FormControl('Nancy', Validators.minLength(2)),
  new FormControl('Drew')
]);

什么时候应该使用一个而不是另一个?

4

4 回答 4

147

FormArray 是 FormGroup 的变体。主要区别在于它的数据被序列化为一个数组(而不是在 FormGroup 的情况下被序列化为一个对象)。当您不知道组中将存在多少控件时,这可能特别有用,例如动态表单。

让我试着用一个简单的例子来解释。假设您有一个表格,您可以在其中捕获客户的披萨订单。然后您放置一个按钮,让他们添加和删除任何特殊请求。这是组件的 html 部分:

<section>
  <p>Any special requests?</p>
  <ul formArrayName="specialRequests">
    <li *ngFor="let item of orderForm.controls.specialRequests.controls; let i = index">
      <input type="text" formControlName="{{i}}">
      <button type="button" title="Remove Request" (click)="onRemoveSpecialRequest(i)">Remove</button>
    </li>
  </ul>
  <button type="button" (click)="onAddSpecialRequest()">
    Add a Request
  </button>
</section>

这是定义和处理特殊请求的组件类:

constructor () {
  this.orderForm = new FormGroup({
    firstName: new FormControl('Nancy', Validators.minLength(2)),
    lastName: new FormControl('Drew'),
    specialRequests: new FormArray([
      new FormControl(null)
    ])
  });
}

onSubmitForm () {
  console.log(this.orderForm.value);
}

onAddSpecialRequest () {
  this.orderForm.controls
  .specialRequests.push(new FormControl(null));
}

onRemoveSpecialRequest (index) {
  this.orderForm.controls['specialRequests'].removeAt(index);
}

FormArray 提供了比 FormGroup 更大的灵活性,因为使用“push”、“insert”和“removeAt”比使用 FormGroup 的“addControl”、“removeControl”、“setValue”等更容易操作 FormControl。FormArray 方法确保控件是在表单的层次结构中正确跟踪。

希望这可以帮助。

于 2017-01-02T08:57:20.420 回答
36

为了创建响应式表单,父级FormGroup是必须的。这FormGroup可以进一步包含formControls, childformGroupsformArray

FormArray还可以包含数组 offormControls或 aformGroup本身。

我们什么时候应该使用formArray?

请阅读这篇漂亮的帖子,它解释了formArray

那个博客中有趣的例子是关于旅行的formGroup

formGroup使用formControland的行程结构formArray如下所示:

this.tripForm = this.fb.group({
    name: [name, Validators.required],
     cities: new FormArray(
       [0] ---> new FormGroup({
           name: new FormControl('', Validators.required),
               places: new FormArray(
                  [0]--> new FormGroup({
                      name: new FormControl('', Validators.required),
                         }),
                      [1]--> new FormGroup({
                         name: new FormControl('', Validators.required),
                      })
                  )
              }), 
       [1] ---> new FormGroup({
           name: new FormControl('', Validators.required),
           places: new FormArray(
               [0]--> new FormGroup({
                   name: new FormControl('', Validators.required),
               }),
               [1]--> new FormGroup({
                   name: new FormControl('', Validators.required),
               })
               )
      }))
})

不要忘记玩这个DEMO,并注意array for citiesand placesof a trip的用法。

于 2018-07-17T19:10:37.230 回答
10

来自:Anton Moiseev 的书“使用 Typescript 进行 Angular 开发,第二版”。:

当您需要以编程方式向表单添加(或删除) 控件时,请使用FormArray。它类似于FormGroup但有一个长度变量。FormGroup表示整个表单或表单字段的固定子集而 FormArray通常表示可以增长或缩小的表单控件的集合

例如,您可以使用FormArray来允许用户输入任意数量的电子邮件。

于 2019-11-06T11:15:29.090 回答
0

从角度文档中,您可以看到

FormArray 是 FormGroup 的替代方法,用于管理任意数量的未命名控件。与表单组实例一样,您可以从表单数组实例中动态插入和移除控件,并且表单数组实例值和验证状态是根据其子控件计算的。但是,您不需要按名称为每个控件定义键,因此如果您事先不知道子值的数量,这是一个很好的选择。

让我向您展示他们的示例,并尝试解释我是如何理解这一点的。您可以在此处查看来源

想象一个表单女巫有以下字段

  profileForm = this.fb.group({
    firstName: ['', Validators.required],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
    aliases: this.fb.array([
      this.fb.control('')
    ])
  });

在这里,我们有firstName,和All 字段一起是表单组,因此我们将所有内容包装在. 同时就像一个子组,所以我们将它包装在另一个中(您可以查看模板以获得更好的理解)!这里的每个表单控件都不同,这意味着您可以像使用. lastNameaddressaliasesgroupaddressgroupkeyaliasesformBuilderpush

这就是我的理解,希望对某人有所帮助。

于 2019-04-05T10:03:19.767 回答