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

Angular 8动态JSON结构递归表单提交问题求助

适配Angular 8动态嵌套JSON对象的递归表单解决方案

我明白你遇到的痛点了——动态嵌套JSON对象的递归表单确实比数组场景棘手,因为Angular的FormGroup和FormArray处理逻辑完全不同,之前的数组方案没法直接套用到对象结构上。下面我给你一套针对性的解决方案,完美适配你给出的JSON结构:

1. 核心:构建递归FormGroup的工具函数

首先咱们需要一个能遍历动态JSON、自动生成对应FormGroup和FormControl的函数。这个函数会判断每个字段的类型:如果是嵌套对象,就递归生成子FormGroup;如果是基本类型,就生成FormControl。

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

// 在你的组件里注入FormBuilder:constructor(private fb: FormBuilder) {}

buildRecursiveForm(data: any): FormGroup {
  const formGroup = this.fb.group({});
  // 遍历当前层级的所有字段
  Object.keys(data).forEach(key => {
    const value = data[key];
    if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
      // 如果是嵌套对象,递归构建子FormGroup
      formGroup.addControl(key, this.buildRecursiveForm(value));
    } else {
      // 基本类型直接创建FormControl
      formGroup.addControl(key, this.fb.control(value));
    }
  });
  return formGroup;
}

2. 初始化父组件表单

在你的父组件里,用上面的函数初始化表单:

export class AppComponent {
  filterFields = { 
    "signature": "[a][b][c][d]", 
    "id": "start3", 
    "passwd": "going", 
    "url": "https://example.com", 
    "code": "ME_GOOD", 
    "type": "ABCD", 
    "main":{ 
      "description": "development", 
      "id": "98gbnuikmvgy6", 
      "name": "satsba", 
      "type": "dcba", 
      "upload": "2019-09-04 18:17:23.222", 
      "by": "example@gmail.com", 
      "version": "0.1"
    }
  };
  filterForm: FormGroup;

  constructor(private fb: FormBuilder) {
    // 初始化递归表单
    this.filterForm = this.buildRecursiveForm(this.filterFields);
  }

  onSubmit() {
    // 提交时直接获取完整的嵌套表单数据
    console.log('表单数据:', this.filterForm.value);
    // 这里就可以拿到包含main子对象的完整数据了
  }
}

3. 创建递归表单组件

接下来咱们需要一个递归组件,用来动态渲染每个层级的表单字段。先创建组件(比如recursive-form.component):

组件类

import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';

@Component({
  selector: 'app-recursive-form',
  templateUrl: './recursive-form.component.html'
})
export class RecursiveFormComponent {
  @Input() formGroup: FormGroup;
  @Input() fields: any; // 当前层级的JSON对象

  // 获取当前层级的所有字段key
  get fieldKeys(): string[] {
    return Object.keys(this.fields);
  }
}

组件模板

<div [formGroup]="formGroup">
  <div *ngFor="let key of fieldKeys">
    <ng-container *ngIf="typeof fields[key] === 'object' && fields[key] !== null && !Array.isArray(fields[key])">
      <!-- 嵌套对象:递归调用自身组件 -->
      <h4>{{ key }}</h4>
      <app-recursive-form 
        [formGroup]="formGroup.get(key) as FormGroup" 
        [fields]="fields[key]">
      </app-recursive-form>
    </ng-container>
    <ng-container *ngIf="typeof fields[key] !== 'object' || Array.isArray(fields[key])">
      <!-- 基本类型:渲染表单控件 -->
      <label>{{ key }}</label>
      <input type="text" [formControlName]="key">
    </ng-container>
  </div>
</div>

4. 父组件模板使用递归组件

最后在父组件的模板里引入这个递归组件:

<form [formGroup]="filterForm" (ngSubmit)="onSubmit()">
  <app-recursive-form 
    [formGroup]="filterForm" 
    [fields]="filterFields">
  </app-recursive-form>
  <button type="submit">提交</button>
</form>

这样处理后,不管你的JSON嵌套多少层对象,表单都会自动递归渲染,而且提交时filterForm.value会完整返回和原始JSON结构一致的表单数据,完美解决你拿不到嵌套字段数据的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:02:54