angular中多层嵌套结构的表单如何处理回显问题

最近在处理angular表单时,有一个4层结构的表单。而且很多元素时动态生成,如下:

复制代码
 this.validateForm=this.fb.group({
      storeId: ["test12"],
      storeNameKey:[''],
      config:this.fb.group({ 
          tableSize:this.fb.group({
              toggle:[false],
              groupSize:this.fb.array([
                this.fb.group({
                  cate:['indoor'],
                  title_en:[''],
                  title_zh:[''],
                  tableSize:this.fb.array([
                    this.fb.group({
                      size: [""],
                      desc_en:["small"],
                      desc_zh: ["小桌"],
                      number:['A02'],
                      preTitle: ["C"],
                      maxPerson: [8],
                      minPerson: [5],
                      alias: "S",
                    }),
                  ])
                }),
                this.fb.group({
                  cate:['outdoor'],
                  title_en:[''],
                  title_zh:[''],
                  tableSize:this.fb.array([
                    this.fb.group({
                      size: ["small"],
                      desc_en:["Small"],
                      desc_zh: ["小桌"],
                      number:['A02'],
                      preTitle: ["C"],
                      maxPerson: [8],
                      minPerson: [5],
                      alias: "S",
                    }),
                  ])
                }),
              ]),
          }),
          hasMoreTableSize:['false'],
          geoFancing:this.fb.group({
            // isOpenGeo:['true'],
            range:[100]
          }),
          dynamicQRCode:this.fb.group({
            refreshEx:[2]
          }),
          isLogin:[false],
          isShowBlockList:[false]
      }),

    })

其界面表现如下:

而在编辑的状态时如何根据后端返回数据结构进行回显。angular中formbuilder对象提供了setValue和patchValue两个方法。这两个方法只对一层对象有效,对于多层嵌套的数据结构,无法生效。经过摸索,发现可以这种方式解决。

首先模拟后端数据结构:

复制代码
const formdata={
  storeId:"disneycart",
  storeNameKey:"123",
  config:{
    tableSize:{
      toggle:true,
      groupSize:[
        {
          cate:"indoor",
          title_en:'',
          title_zh:'',
          tableSize:[
            {
              alias: "S",
              desc_en: "small",
              desc_zh: "小4桌",
              maxPerson: 4,
              minPerson: 1,
              number: "A01",
              preTitle: "A",
              size: "small"
            },
            {
              alias: "m",
              desc_en: "middl",
              desc_zh: "中桌",
              maxPerson: 6,
              minPerson: 4,
              number: "b01",
              preTitle: "B",
              size: "middle"
            },
            {
              alias: "L",
              desc_en: "large",
              desc_zh: "中桌",
              maxPerson: 6,
              minPerson: 4,
              number: "b01",
              preTitle: "c",
              size: "large"
            },
            
          ]
        },
        {
          cate:"outdoor",
          title_en:'',
          title_zh:'',
          tableSize:[
            {
              alias: "S",
              desc_en: "small",
              desc_zh: "小4桌",
              maxPerson: 4,
              minPerson: 1,
              number: "A01",
              preTitle: "A",
              size: "small"
            },
            {
              alias: "m",
              desc_en: "middl",
              desc_zh: "中桌",
              maxPerson: 6,
              minPerson: 4,
              number: "b01",
              preTitle: "B",
              size: "middle"
            }
          ]
        }
      ]
    },
    dynamicQRCode:{
      refreshEx:200
    },
    geoFancing:{
      range:200.,
      // isOpenGeo:false
    },
    hasMoreTableSize:true,
    isLogin:true,
    isShowBlockList:true
  }    
}

我们在页面初始化的时候模拟把该数据返回给前端进行回显。

复制代码
  ngAfterViewInit(){
    setTimeout(()=>{
      this.repatchForm(formdata)
      console.log("settimeout---后", this.validateForm)
    },2000)
  }

repatchForm(responseData:any){
    let arr2=this.resetAndGetGroupSize(responseData)            
    console.log("settimeout---前", this.validateForm)
    this.validateForm.patchValue({
      storeId: responseData.storeId,
      storeNameKey: responseData.storeNameKey,
      config: {
        tableSize: {
          toggle: responseData.config.tableSize.toggle,
          groupSize: arr2
        },
        hasMoreTableSize: responseData.config.hasMoreTableSize,
        geoFancing: {
          range: responseData.config.geoFancing.range
        },
        dynamicQRCode: {
          refreshEx: responseData.config.dynamicQRCode.refreshEx
        },
        isLogin:responseData.config.isLogin,
        isShowBlockList:responseData.config.isShowBlockList
      }
    });
  }

注意此处是核心 ,我们新建一个新的formGroup对象,然后通过表单对象把原本里面的group干掉

最后通过patchValue进行重新复制。 这里特别注意我们清空原本的groupSize对象,最后通过遍历新的后端数据生成新的formArray对象,最后把这个新的formArray对象通过patchValue的方式进行重新赋值即可生效。

复制代码
//处理会显时table列表数据
  resetAndGetGroupSize(resData:any){
    let arr=resData?.config?.tableSize?.groupSize.map((group: any) => {
      return this.fb.group({
        cate: group.cate,
        title_en: group.title_en,
        title_zh: group.title_zh,
        tableSize: this.fb.array(group.tableSize.map((table: any) => {
          return this.fb.group({
            size: table.size,
            desc_en: table.desc_en,
            desc_zh: table.desc_zh,
            number: table.number,
            preTitle: table.preTitle,
            maxPerson: table.maxPerson,
            minPerson: table.minPerson,
            alias: table.alias
          });
        }))
      })
    })
    this.groupSize.clear()
    arr.forEach((item:FormGroup)=>{
      this.groupSize.push(item)
    })
    let arr2=arr.map((item:FormGroup)=>{
      return item.value
    })
    return arr2
  }
相关推荐
徐小夕@趣谈前端6 分钟前
Web文档的“Office时刻“:jitword共建版2.0发布!让浏览器变成本地生产力
前端·数据结构·vue.js·算法·开源·编辑器·es6
Data_Journal18 分钟前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php
德育处主任Pro19 分钟前
纯前端网格路径规划:PathFinding.js的使用方法
开发语言·前端·javascript
墨笔.丹青25 分钟前
基于QtQuick开发界面设计出简易的HarmonyUI界面----下
开发语言·前端·javascript
董世昌4142 分钟前
深度解析浅拷贝与深拷贝:底层逻辑、实现方式及实战避坑
前端·javascript·vue.js
扶苏10021 小时前
vue使用event.dataTransfer实现A容器数据拖拽复制到到B容器
前端·vue.js·chrome
David凉宸1 小时前
Vue 3 项目的性能优化策略:从原理到实践
前端·vue.js·性能优化
小马_xiaoen1 小时前
Proxy 与 Reflect 从入门到实战:ES6 元编程核心特性详解
前端·javascript·ecmascript·es6
hoiii1871 小时前
MATLAB SGM(半全局匹配)算法实现
前端·算法·matlab
摘星编程2 小时前
React Native + OpenHarmony:ImageSVG图片渲染
javascript·react native·react.js