最近在处理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}