介绍
在 Angular 2+ 中,响应式表单可用于管理表单的状态。FormArray
用于跟踪表单字段的值和有效性状态。您可以FormArray
在 Reactive Forms 中使用响应用户事件动态添加表单字段。
FormArray
用作环绕任意数量的FormControl
、FormGroup
甚至其他FormArray
实例的数组。FormArray
您可以通过声明方式添加新的表单域或一组表单域。
在本文中,我们将介绍一个示例应用程序,其中包含用于购买商品的订单表单。我们将设计此表单以附加一个新的表单字段,供用户将商品添加到他们的订单中。
先决条件
要阅读本文,您需要:
- Node.js 安装在本地,您可以按照如何安装 Node.js 和创建本地开发环境来完成。
- 对 Angular 有一个基本的了解。要了解有关 Angular 的更多信息,请查看Angular 主题页面。
这篇文章还假设您是从一个由@angular/cli
. 如果您开始使用 Angular CLI,可以参考这篇文章。
步骤 1 — 导入FormArray
和初始化表单
首先,确保您ReactiveFormsModule
在应用程序中导入。
在 中app.module.ts
,从 Angular模块添加一个import
for :ReactiveFormsModule
forms
// ...
import { ReactiveFormsModule } from '@angular/forms';
此外,添加ReactiveFormsModule
到模块的数组imports
:
@NgModule({
...
imports: [
...
ReactiveFormsModule
]
...
})
在 中app.component.ts
,添加来自 Angular模块的import
of FormBuilder
、FormGroup
和:FormArray
forms
// ...
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
接下来,您将使用初始化形式FormBuilder
在ngOnInit
钩:
// ...
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
将包括一个的customerName
,email
和一个的阵列items
。
请注意,该items
实例是 aFormArray
而不是 a FormControl
。我们正在调用一个createItem
方法来创建 aFormGroup
作为数组中的第一项。
接下来,我们将createItem
方法添加到AppComponent
:
// ...
export class AppComponent {
// ...
createItem(): FormGroup {
return this.formBuilder.group({
name: '',
description: '',
price: ''
});
}
}
在我们的例子中,item
将包括的name
,description
和price
。
现在,我们有一个orderForm
and items
。我们仍然需要实现一种动态添加新项目的方法。
第 2 步 –FormArray
动态添加到
我们可以FormArray
像对待常规数组一样对待我们,并将新项目推入其中。将addItem
方法添加到AppComponent
:
// ...
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
,用我们的新模板替换内容:
<form [formGroup]="orderForm">
<div
formArrayName="items"
*ngFor="let item of orderForm.get('items')['controls']; let i = index;"
>
...
</div>
...
</form>
接下来,让我们添加我们FormGroup
的FormControls
foritem
内部FormArray
:
<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()
:
<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
通过遍历表单添加一些代码来显示模板中的值:
<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 name
、description
、 和price
,我们就可以单击“添加项目”按钮,一个新项目就会动态地附加到表单中。
结论
您已经完成了对 Angular 2+ Reactive Forms 如何FormArray
用于动态添加新表单字段的探索。这种模式对于用户可能需要多次输入数据的场景很有用。
如果您想了解有关 Angular 的更多信息,请查看我们的 Angular 主题页面,了解练习和编程项目。