如何在 Angular 中使用 FormArray 动态创建表单字段

介绍

在 Angular 2+ 中,响应式表单可用于管理表单的状态。FormArray用于跟踪表单字段的值和有效性状态。您可以FormArray在 Reactive Forms 中使用响应用户事件动态添加表单字段。

FormArray用作环绕任意数量的FormControlFormGroup甚至其他FormArray实例的数组FormArray您可以通过声明方式添加新的表单域或一组表单域。

在本文中,我们将介绍一个示例应用程序,其中包含用于购买商品的订单表单。我们将设计此表单以附加一个新的表单字段,供用户将商品添加到他们的订单中。

先决条件

要阅读本文,您需要:

这篇文章还假设您是从一个由@angular/cli. 如果您开始使用 Angular CLI,可以参考这篇文章

步骤 1 — 导入FormArray和初始化表单

首先,确保您ReactiveFormsModule在应用程序中导入

在 中app.module.ts从 Angular模块添加一个importfor ReactiveFormsModuleforms

src/app/app.module.ts
// ...
import { ReactiveFormsModule } from '@angular/forms';

此外,添加ReactiveFormsModule到模块的数组imports

src/app/app.module.ts
@NgModule({
  ...
  imports: [
    ...
    ReactiveFormsModule
  ]
  ...
})

在 中app.component.ts,添加来自 Angular模块importof FormBuilderFormGroupFormArrayforms

src/app/app.component.ts
// ...
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';

接下来,您将使用初始化形式FormBuilderngOnInit钩:

src/app/app.component.ts
// ...

export class AppComponent {
  orderForm: FormGroup;
  items: FormArray;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit() {
    this.orderForm = this.formBuilder.group({
      customerName: '',
      email: '',
      items: this.formBuilder.array([ this.createItem() ])
    });
  }
}

在该示例中,orderForm将包括一个的customerNameemail和一个的阵列items

请注意,该items实例是 aFormArray而不是 a FormControl我们正在调用一个createItem方法来创建 aFormGroup作为数组中的第一项。

接下来,我们将createItem方法添加AppComponent

src/app/app.component.ts
// ...

export class AppComponent {
  // ...

  createItem(): FormGroup {
    return this.formBuilder.group({
      name: '',
      description: '',
      price: ''
    });
  }
}

在我们的例子中,item将包括的namedescriptionprice

现在,我们有一个orderFormand items我们仍然需要实现一种动态添加新项目的方法。

第 2 步 –FormArray动态添加到

我们可以FormArray对待常规数组一样对待我们,并将新项目推入其中。addItem方法添加AppComponent

src/app/app.component.ts
// ...

export class AppComponent {
  // ...

  addItem(): void {
    this.items = this.orderForm.get('items') as FormArray;
    this.items.push(this.createItem());
  }
}

现在我们已经addItem()定义了。addItem当用户点击添加新项目时,我们仍然需要调用模板中的方法。

让我们使用formArrayName模板中指令绑定到FormArray. 在 中app.component.html,用我们的新模板替换内容:

src/app/app.component.html
<form [formGroup]="orderForm">
  <div
    formArrayName="items"
    *ngFor="let item of orderForm.get('items')['controls']; let i = index;"
  >
    ...
  </div>
  ...
</form>

接下来,让我们添加我们FormGroupFormControlsforitem内部FormArray

src/app/app.component.html
<form [formGroup]="orderForm">
  <div
    formArrayName="items"
    *ngFor="let item of orderForm.get('items')['controls']; let i = index;"
  >
    <div [formGroupName]="i">
      <input formControlName="name" placeholder="Item name">
      <input formControlName="description" placeholder="Item description">
      <input formControlName="price" placeholder="Item price">
    </div>
  </div>
  ...
</form>

请注意formGroupName指令现在如何采用索引而不是名称。我们使用ngFor给我们的索引设置它

在 之后FormArray,让我们添加一个按钮,点击时调用addItem()

src/app/app.component.html
<form [formGroup]="orderForm">
  <div
    formArrayName="items"
    *ngFor="let item of orderForm.get('items')['controls']; let i = index;"
  >
    <div [formGroupName]="i">
      <input formControlName="name" placeholder="Item name">
      <input formControlName="description" placeholder="Item description">
      <input formControlName="price" placeholder="Item price">
    </div>
  </div>
  <button type="button" (click)="addItem()">Add Item</button>
</form>

出于调试目的,我们可以FormControl通过遍历表单添加一些代码来显示模板中的值:

src/app/app.component.html
<form [formGroup]="orderForm">
  <div
    formArrayName="items"
    *ngFor="let item of orderForm.get('items')['controls']; let i = index;"
  >
    <div [formGroupName]="i">
      <input formControlName="name" placeholder="Item name">
      <input formControlName="description" placeholder="Item description">
      <input formControlName="price" placeholder="Item price">
    </div>
    Exposed item name: {{ orderForm.controls.items.controls[i].controls.name.value }}
  </div>
  <button type="button" (click)="addItem()">Add Item</button>
</form>

此时,我们有一个以单个项目开头的表单。一旦我们为第一个项目输入 a namedescription、 和price,我们就可以单击“添加项目”按钮,一个新项目就会动态地附加到表单中。

结论

您已经完成了对 Angular 2+ Reactive Forms 如何FormArray用于动态添加新表单字段的探索这种模式对于用户可能需要多次输入数据的场景很有用。

如果您想了解有关 Angular 的更多信息,请查看我们的 Angular 主题页面,了解练习和编程项目。

觉得文章有用?

点个广告表达一下你的爱意吧 !😁