angular表单的三大基本构造块
1.FormControl:单个独立的表单控件;
2.FormGroup:一组FormControl实例;
3.FormArray:控件数组,控件可为FormControl、FormGroup、FormArray的实例;
FormBuilder: 根据用户指定的配置创建 abstractControl,FormBuilder
提供的语法糖可快速实例化 FormControl
、FormGroup
、FormArray
。
- this.formBuilder.control() ;
- this.formBuilder.group();
- this.formBuilder.array()
FormArray 的使用场景:需要循环遍历的表格,实现动态增加或删除表数据
常用方法:
- at($index); 获取数组中位于index处的控件
- push(); 数组末尾插入新的控件
- removeAt($index) ; 移除数组中位于index处的控件
- patchValue(); 赋值
DEMO1
this.userModel = this.formBuilder.group({
name: ['', Validator.compose(...)],
detailInfoModel: ['', this.formBuilder.array([this.initDetailInfo()])],
})
// 初始化FormArray detailInfo
initDetailInfoModel() {
return this.formBuilder.group({
phone: [''],
salary: [0],
extraMony: [0],
TotalCount: []
})
}
get detailInfoModel() {
return this.userModel.get('detailInfoModel') as FormArray;
}
// 将获取的详情数据循环赋给表单组detailInfoModel
this.detailInfo = [{phone: 11, salary:11,...},{...}];
this.detailInfo.map((item,index) => {
this.detailInfoModel.at(index).patchValue({
phone: item.phone,
salary: Number(item.salary),
extraMony: Number(item.extraMony),
TotalCount: item.TotalCount
})
})
html表格中如果有合计需要动态计算,可在合计中使用ngModel绑定需要累加的控件值
<form [formGroup]="userModel">
<table>
<thead>
<tr>
<th>电话</th>
<th>薪水</th>
<th>额外薪水</th>
<th>合计</th>
</tr>
</thead>
<tbody formArrayName="detailInfoModel">
<ng-container *ngFor="let item of userModel.get('detailInfoModel').controls as FormArray; let i = index" [formGroupName]="i">
<tr>
<td><input type="text" class="form-control" formControlName="phone"></td>
<td><input type="number" class="form-control" formControlName="salary"></td>
<td><input type="number" class="form-control" formControlName="extraMony"></td>
<td><input type="number" class="form-control" formControlName="TotalCount"
[ngModel]="item.controls.salary.value + item.controls.extraMony.value">
</td>
</tr>
</ng-container>
</tbody>
</table>
</form>
DEMO2
场景描述:在一个 form 表单中,需要动态添加或删除某个表单集
创建表单组
/**
* 创建表单
*/
private createForm() {
this.detailForm = this.fb.group({
name: [''],
exotic_details: this.fb.array([])
});
this.addFormArrayItem();
}
/**
* 定义 formArray
*/
private newFormArrayItem(): FormGroup {
return this.fb.group({
strike_price: [],
strike_schedule_type: [],
payout: []
});
}
/**
* 添加表单组项
*/
public addFormArrayItem() {
this.exoticDetails.push(this.newFormArrayItem());
}
/**
* 删除表单组项
*/
public removeFormArrayItem(index) {
this.exoticDetails.removeAt(index);
}
/**
* 获取 formArray 表单
*/
get exoticDetails(): FormArray {
return this.detailForm.get('exotic_details') as FormArray;
}
/**
* formArray 赋值
* @param value:与formArray对应的数组 [{strike_price: '', payout: '', ...}, ...]
*/
private setFormArrayValues(item) {
this.exoticDetails.patchValue(item);
}
页面中使用
<form [formGroup]="detailForm " (ngSubmit)="onSubmit()">
<p>
<label for="name">Name </label>
<input type="text" id="name" name="name" formControlName="name">
</p>
<div formArrayName="exotic_details">
<div *ngFor="let item of exoticDetails.controls; let i=index">
<div [formGroupName]="i">
<input type="text" formControlName="payout">
<button (click)="removeFormArrayItem(i)">delete</button>
</div>
</div>
</div>
<p>
<button type="submit">Submit</button>
</p>
</form>
<p>
<button type="button" (click)="addFormArrayItem()">add</button>
</p>