何时使用FormGroup与FormArray?

时间:2016-12-22 17:39:13

标签: angular angular2-forms

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'),
]);

何时应该使用另一个?

4 个答案:

答案 0 :(得分:73)

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”等更容易操作FormControls.FormArray方法确保控件在表单的层次结构中正确跟踪。

希望这会有所帮助。

答案 1 :(得分:11)

为了创建反应形式,必须有一个父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的数组用法。

答案 2 :(得分:1)

来自:Anton Moiseev书“带打字稿的角度开发,第二版。”:

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

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

答案 3 :(得分: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方法像简单数组一样将其值尽可能多地推入。

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