【angular-实践】由数据生成表单,多层嵌套

readme

将value为string和[]的添加分别抽出来,就能实现无限层的嵌套,代码就懒得放了。。。前面写的时候经验少,没考虑好

需求

根据数组生成不定数量的表单项,数组中的value项可能为数组,可能为字符串

效果

ui_typeeditbox是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))
  }

}

参考

【angular-实践】动态增加表单(一层,多层表单嵌套)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值