You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular14中创建树形结构的Form Array?

实现Angular动态嵌套树形结构Form Array的方案

核心思路

嵌套树形结构的Form Array本质是在FormGroup/FormArray中嵌套FormArray,每个节点既可以是表单控件,也可以包含子节点的FormArray。我们需要实现两个核心功能:

  • 动态添加/删除节点(包括子节点)
  • 模板递归渲染树形结构

步骤实现

1. 定义树形节点的表单结构

在组件类中定义节点的基础FormGroup模板,每个节点包含自身字段和子节点数组:

import { FormBuilder, FormGroup, FormArray } from '@angular/forms';

// 定义单个节点的FormGroup
createNode(): FormGroup {
  return this.fb.group({
    name: ['', Validators.required],
    // 子节点数组,初始为空
    children: this.fb.array([])
  });
}

// 初始化根节点数组
rootNodes = this.fb.array([this.createNode()]);

2. 实现节点操作方法

编写添加/删除节点的方法,支持操作子节点数组:

// 向指定FormArray添加节点
addNode(parentArray: FormArray): void {
  parentArray.push(this.createNode());
}

// 从指定FormArray删除节点
removeNode(parentArray: FormArray, index: number): void {
  parentArray.removeAt(index);
}

3. 递归模板渲染

利用Angular的ng-template和ngTemplateOutlet实现递归渲染,传递当前节点的FormArray:

<form [formGroup]="form">
  <div formArrayName="rootNodes">
    <!-- 递归模板 -->
    <ng-template #nodeList let-nodes="nodes">
      <div *ngFor="let node of nodes.controls; let i = index" [formGroupName]="i">
        <input formControlName="name" placeholder="节点名称">
        <button (click)="addNode(node.get('children') as FormArray)">添加子节点</button>
        <button (click)="removeNode(nodes, i)" *ngIf="nodes.length > 1">删除节点</button>
        
        <!-- 递归渲染子节点 -->
        <div formArrayName="children" class="ml-4" *ngIf="(node.get('children') as FormArray).length > 0">
          <ng-container *ngTemplateOutlet="nodeList; context:{nodes: node.get('children')}"></ng-container>
        </div>
      </div>
    </ng-template>

    <!-- 渲染根节点 -->
    <ng-container *ngTemplateOutlet="nodeList; context:{nodes: rootNodes}"></ng-container>
  </div>
</form>

4. 组件初始化

在组件构造函数中注入FormBuilder,并初始化根表单:

form: FormGroup;

constructor(private fb: FormBuilder) {
  this.form = this.fb.group({
    rootNodes: this.rootNodes
  });
}

关键注意事项

  • 递归模板必须通过ng-template实现,避免重复代码
  • 操作子节点时,要确保正确获取当前节点的children FormArray,注意类型转换
  • 可按需给表单字段添加验证规则,比如示例中的name必填验证

内容的提问来源于stack exchange,提问作者Arunkumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:17:05