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 という 2 つのメソッドが用意されています。これら 2 つの方法は 1 レベルのオブジェクトに対してのみ有効であり、複数レベルのネストされたデータ構造に対しては有効ではありません。いろいろ調べた結果、この方法で解決できることが分かりました。

まずバックエンドのデータ構造をシミュレートします。

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 オブジェクトを作成し、その form オブジェクトを使用して内部の元のグループを削除します。

最後に、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
  }

 

 

おすすめ

転載: blog.csdn.net/baidu_41601048/article/details/132759131