如何使用Angular 8创建支持深层嵌套的递归动态表单
Angular 任意层级递归动态表单实现方案
问题核心成因
- 初始调用递归模板未传递父分组参数,根层级字段渲染时读取空值触发UI崩溃
- 原有普通字段模板强制绑定
formGroupName,无父分组的根层级字段绑定该属性会抛出响应式表单错误 - 递归上下文的父分组传递逻辑不符合Angular嵌套FormGroup的层级对应规则
- 测试用JSON结构的
group属性放置位置错误,需作为嵌套分组字段的自有属性,而非与普通字段平级
标准嵌套JSON结构示例
const filterFields = [ { key: "common", title: "main fields", group: [ { key: "createdAt", title: "Create Date", type: "date" }, { key: "subGroup", title: "二级分组", group: [ { key: "foo", title: "Foo", type: "select", }, { key: "goo", title: "Goo", type: "input", }, // 可无限新增嵌套分组 { key: "thirdGroup", title: "三级分组", group: [ { key: "bar", title: "Bar", type: "input" } ] } ] } ] } ]
修改后支持无限嵌套的模板代码
<form [formGroup]="filterForm" class="filter-form"> <ng-template #recursiveList let-filterFields let-parentGroup="parentGroup"> <ng-container *ngFor="let item of filterFields"> <!-- 处理嵌套分组 --> <ng-container *ngIf="item.group; else defaultField"> <p>{{item.key}}</p> <!-- 非根层级分组处理 --> <div [formGroupName]="item.key" *ngIf="parentGroup"> <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.group, parentGroup: item.key }"></ng-container> </div> <!-- 根层级分组处理 --> <div [formGroup]="filterForm" *ngIf="!parentGroup"> <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: item.group, parentGroup: item.key }"></ng-container> </div> </ng-container> <!-- 处理普通表单字段 --> <ng-template #defaultField> <div class="form-group"> <!-- 有父分组的字段绑定 --> <input *ngIf="parentGroup" [type]="item.type" [formControlName]="item.key" [placeholder]="item.title" [name]="item.key" /> <!-- 根层级字段绑定 --> <input *ngIf="!parentGroup" [type]="item.type" [formControl]="filterForm.get(item.key)" [placeholder]="item.title" [name]="item.key" /> </div> </ng-template> </ng-container> </ng-template> <!-- 初始调用不传入parentGroup标识为根层级 --> <ng-container *ngTemplateOutlet="recursiveList; context:{ $implicit: filterFields }"></ng-container> </form>
TS端配套修改说明
需要同步实现递归生成嵌套FormGroup的逻辑,不能仅生成扁平表单结构,参考代码:
import { FormBuilder, FormGroup } from '@angular/forms'; export class AppComponent { filterForm: FormGroup; filterFields = [] // 替换为你的JSON结构 constructor(private fb: FormBuilder) {} ngOnInit() { this.filterForm = this.fb.group({}); this.buildFormGroup(this.filterFields, this.filterForm); } // 递归生成嵌套FormGroup buildFormGroup(fields: any[], parentGroup: FormGroup) { fields.forEach(item => { if (item.group) { const subGroup = this.fb.group({}); parentGroup.addControl(item.key, subGroup); this.buildFormGroup(item.group, subGroup); } else { parentGroup.addControl(item.key, this.fb.control('')); } }); } }
以上修改完成后即可支持任意层级的递归嵌套表单,不会出现层级加深后UI崩溃的问题。
内容的提问来源于stack exchange,提问作者RoyBarOn
相关产品推荐
相关产品推荐

