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