何时使用FormGroup与FormArray?

问题描述 投票:51回答:3

FormGroup

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

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

FormArray

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

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

应该何时使用另一个?

angular angular2-forms
3个回答
77
投票

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

让我试着通过一个简单的例子来解释。比如,您有一个表单,您可以在其中捕获客户对Pizza的订单。然后你放一个按钮让他们添加和删除任何特殊请求。这是组件的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方法确保控件是在表单的层次结构中正确跟踪。

希望这可以帮助。


14
投票

为了创建一个反应形式,父母FormGroup是必须的。这个FormGroup可以进一步包含formControls,儿童formGroupsformArray

FormArray可以进一步包含formControlsformGroup本身的数组。

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

请阅读这个美丽的post,它解释了formArray的用法

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

使用formGroupformControl的旅行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,并注意到旅行的citiesplaces阵列的使用。


0
投票

从角度文档中你可以看到

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

让我告诉你他们的例子并试着解释我是如何理解这一点的。你可以看到源here

想象一下一个女巫有以下领域的形式

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

在这里我们有firstNamelastNameaddressaliases所有字段在一起是形式组,所以我们包装在group的一切。同时address就像一个子组,所以我们将它包装在另一个group(你可以看看模板以便更好地理解)!除了key之外,每个表单控件都是aliases,这意味着你可以使用像formBuilder这样的push方法尽可能多地推送它。

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

© www.soinside.com 2019 - 2024. All rights reserved.