readme
将value为string和[]的添加分别抽出来,就能实现无限层的嵌套,代码就懒得放了。。。前面写的时候经验少,没考虑好
需求
根据数组生成不定数量的表单项,数组中的value项可能为数组,可能为字符串
效果
ui_type
为editbox
是value是字符串;为editboxes
时是数组
interface T {
key: string,
value: any,
ui_type: string,
ui_title: string
}
testData: T[] = [
{
"key": "title",
"value": "1-1数据",
"ui_type": "editbox",
"ui_title": "1-1"
},
{
"key": "fireTime",
"value": [
{
"key": "fireTime1",
"value": "2-1数据",
"ui_type": "editbox",
"ui_title": "2-1"
},
{
"key": "fireTime2",
"value": "2-2数据",
"ui_type": "editbox",
"ui_title": "2-2"
}
],
"ui_type": "editboxes",
"ui_title": "1-2"
}
]
// 初始化后的表单形如
this.validateForm = this.fb.group({
generateFormData: this.fb.array([
// 表单初始化后的形式:
this.fb.group({
key: [null, [Validators.required]],
ui_title: [null, [Validators.required]],
ui_type: [null, [Validators.required]],
value: this.fb.array([
this.fb.group({
key: [null, [Validators.required]],
ui_type: [null, [Validators.required]],
ui_title: [null, [Validators.required]],
value: [null, [Validators.required]],
})
]),
})
])
});
源码
.html
<button (click)="showFormValue()">查看表单值</button>
<nz-divider [nzText]="'表单嵌套'"></nz-divider>
<form [formGroup]="validateForm">
<nz-form-item>
<div></div>
<nz-form-control nzSpan="24">
<div class="workFlowContent" formArrayName="generateFormData" *ngFor="let content of generateFormData.controls;
let workflowIndex = index">
<div [formGroupName]="workflowIndex.toString()">
<nz-row>formGroupName: {{workflowIndex}}</nz-row>
<nz-row>
<nz-form-label nzSpan="4" nz-col>key</nz-form-label>
<nz-form-control nz-col nzSpan="7">
<input nz-input type="text" formControlName="key">
</nz-form-control>
</nz-row>
<nz-row>
<nz-form-label nzSpan="4" nz-col>ui_type</nz-form-label>
<nz-form-control nz-col nzSpan="7">
<input nz-input type="text" formControlName="ui_type">
</nz-form-control>
</nz-row>
<!-- value -->
<ng-container *ngIf="getValue(content).controls == undefined; else other_ediboxes">
<nz-row>
<nz-form-label nzSpan="4">
value
</nz-form-label>
<nz-form-control nz-col nzSpan="7">
<input nz-input type="text" formControlName="value">
</nz-form-control>
</nz-row>
</ng-container>
<ng-template #other_ediboxes>
<nz-row>
<nz-form-label nz-col nzSpan="4">
value
</nz-form-label>
<nz-form-control nz-col nzSpan="20">
<div formArrayName="value" class="stageContent" *ngFor="let stage of getValue(content).controls;
let stageIndex = index">
<div [formGroupName]="stageIndex.toString()">
<nz-row>formGroupName: {{stageIndex}}</nz-row>
<nz-row>
<nz-form-label nzSpan="8" nz-col>key</nz-form-label>
<nz-form-control nzSpan="16" nz-col>
<input nz-input type="text" formControlName="key" placeholder="请输入">
</nz-form-control>
</nz-row>
<nz-row>
<nz-form-label nzSpan="8" nz-col>ui_type</nz-form-label>
<nz-form-control nzSpan="16" nz-col>
<input nz-input type="text" formControlName="ui_type" placeholder="请输入">
</nz-form-control>
</nz-row>
</div>
</div>
</nz-form-control>
</nz-row>
<nz-row>
</nz-row>
</ng-template>
</div>
</div>
</nz-form-control>
</nz-form-item>
</form>
<nz-form-item>
<nz-form-label nzSpan="3" nz-col>
表单的值
</nz-form-label>
<nz-form-control nzSpan="21" nz-col>
{{validateForm.value | json}}
</nz-form-control>
</nz-form-item>
.ts
import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
interface T {
key: string,
value: any,
ui_type: string,
ui_title: string
}
@Component({
selector: 'uv-update-conf3',
templateUrl: './update-conf3.component.html',
styleUrls: ['./update-conf3.component.css']
})
export class UpdateConf3Component implements OnInit {
testData: T[] = [
{
"key": "title",
"value": "1-1数据",
"ui_type": "editbox",
"ui_title": "1-1"
},
{
"key": "fireTime",
"value": [
{
"key": "fireTime1",
"value": "2-1数据",
"ui_type": "editbox",
"ui_title": "2-1"
},
{
"key": "fireTime2",
"value": "2-2数据",
"ui_type": "editbox",
"ui_title": "2-2"
}
],
"ui_type": "editboxes",
"ui_title": "1-2"
}
]
public validateForm: FormGroup;
constructor(private fb: FormBuilder) {
this.validateForm = this.fb.group({
generateFormData: this.fb.array([
// 表单初始化后的形式:
// this.fb.group({
// key: [null, [Validators.required]],
// ui_title: [null, [Validators.required]],
// ui_type: [null, [Validators.required]],
// value: this.fb.array([
// this.fb.group({
// key: [null, [Validators.required]],
// ui_type: [null, [Validators.required]],
// ui_title: [null, [Validators.required]],
// value: [null, [Validators.required]],
// })
// ]),
// })
])
});
// 初始化表单
this.testData.forEach((e: any, index: number) => {
if (e.ui_type == "editboxes") {
this.addValueArr(e, index)
} else {
this.addValueStr(e, index)
}
})
}
// 获取generateFormData的formControls
get generateFormData(): FormArray {
return this.validateForm.get('generateFormData') as FormArray;
}
// 获取gcontent对应的value的formControls
getValue(content: any) {
return content.get('value') as FormArray;
}
ngOnInit() {
}
// value为[], 初始化为FormArray类型
public addValueArr(e: any, index: number): void {
this.generateFormData.push(
this.fb.group({
key: [e.key, [Validators.required]],
ui_type: [e.ui_type, [Validators.required]],
ui_title: [e.ui_title, [Validators.required]],
value: this.fb.array([
]),
})
);
// 初始化value
const subValue = e.value
subValue.forEach((sub: any) => {
this.addValueItem(sub, index)
})
}
// value为字符串,初始化为FormControl类型
public addValueStr(e: any, index: number): void {
this.generateFormData.push(
this.fb.group({
key: [e.key, [Validators.required]],
ui_type: [e.ui_type, [Validators.required]],
ui_title: [e.ui_title, [Validators.required]],
value: [e.value, [Validators.required]]
})
);
}
// 第一层value:FormArray 添加子项
public addValueItem(e: any, workflowIndex: number) {
(this.generateFormData.at(workflowIndex).get('value') as FormArray).push(
this.fb.group({
key: [e.key, [Validators.required]],
ui_type: [e.ui_type, [Validators.required]],
ui_title: [e.ui_title, [Validators.required]],
value: [e.value, [Validators.required]]
}));
}
showFormValue() {
console.log(this.validateForm)
console.log(JSON.stringify(this.validateForm.value, undefined, 2))
}
}