如何使用angular基于提供的JSON数据构建嵌套式响应式表单结构



我是angular的新手。下面是我从GET调用中得到的JSON数据。我正在尝试使用这个

构建表单
data = {
headline: [
{
language: 'en',
headlineText: 'example headline',
},
],
bodyText: [
{
language: 'en',
bodyText: 'example bodytext',
},
],
location: {
name: 'mkontheway',
openingHours: [
{
day: 'Mon-frd',
timing: '10.00PM-9AM',
},
],
address: {
postCode: 'test',
country: 'test',
},
},
};

但是这里Day和Timing字段重复了2次。由于嵌套的表单结构,我无法正确地控制这两个字段。请有人建议我的解决方案,以建立一个复杂的嵌套表单结构在角。

提前感谢。

这是堆栈闪电战链接

Angular嵌套表单

这里有嵌套的表单组和表单数组。请告诉我如何使用angular响应式表单实现这个嵌套表单

我引用了这个堆栈闪电战的例子参考栈闪电战

您只需要创建一个formArray在openingHours中

this.createAppForm = this.fb.group({
...
location: this.fb.group({
name: ['', Validators.required],
openingHours: this.fb.array([]), //<--this is an "empty" formAray
address: this.fb.group({
...
}),
}),
});

但是(总是有一个但是)看到你的代码,你有很多重复创建不同的FormGroups。重复代码会让我们更早地陷入麻烦。

我们将创建函数返回FormGroup

组合的FormGroup假设你有一些像

setHeadLine(data: any = null) {
data = data || { language: null, headlineText: null };
return this.fb.group({
headlineText: data.headlineText,
language: data.language,
});
}
setBodyText(data: any = null) {
data = data || { bodyText: null, language: null };
return this.fb.group({
bodyText: data.bodyText,
language: data.language,
});
}
setAddress(data: any = null) {
data = data || { postCode: null, country: null };
return this.fb.group({
postCode: [data.postCode, Validators.required],
country: [data.country, Validators.required],
});
}
setOpeningHour(data: any = null) {
data = data || { day: null, timing: null };
return this.fb.group({
day: [data.day, Validators.required],
timing: [data.timing, Validators.required],
});
}
setLocation(data: any = null) {
console.log(data);
data = data || { name: null, openingHours: null, address: null };
return this.fb.group({
name: [data.name, Validators.required],
openingHours: this.fb.array(
data.openingHours
? data.openingHours.map((x) => this.setOpeningHour(x))
: []
),
address: this.setAddress(data.address),
});
}

看看setLocation"调用setAddress函数来创建formGroup地址,以及openingHours是一个this.fb.数组。如果数据。openingHours是一个数组,将对象数组转换为formGroups数组并创建formmarray,否则返回一个空数组

最后创建一个函数返回formGroup

setFormGroup(data: any = null) {
data = data || { headline: null, bodyText: null, location: null };
return this.fb.group({
headline: this.fb.array(
data.headline ? data.headline.map((x) => this.setHeadLine(x)) : []
),
bodyText: this.fb.array(
data.bodyText ? data.bodyText.map((x) => this.setBodyText(x)) : []
),
location: this.setLocation(data.location),
});
}

这样你就不会重复代码了。在构造函数中可以写

this.createAppForm = this.setFormGroup(this.data);

当您添加FormGroup时,只需调用函数:

addHeadline() {
this.getHeadlineFormData().push(this.setHeadLine())
}
addBodyText() {
this.getBodyTextFormData().push(this.setBodyText())
}
addOpeningHours() {
this.getopeningHoursFormData().push(this.setOpeningHour())
}

好吧,(最后这只是一个建议)我认为使用" get& quot;代码会变得更清晰,所以如果你替换

//replace
getHeadlineFormData() {
return <FormArray>this.createAppForm.get('headline');
}
//by 
get headlineFormData() {
return <FormArray>this.createAppForm.get('headline');
}
//replace
getBodyTextFormData() {
return <FormArray>this.createAppForm.get('bodyText');
}
//by
get bodyTextFormData() {
return <FormArray>this.createAppForm.get('bodyText');
}
//replace
getLocationFormData() {
return <FormArray>this.createAppForm.get('location');
}
//by
get locationFormData() {
return <FormArray>this.createAppForm.get('location');
}
//and replace
getopeningHoursFormData() {
return <FormArray>this.createAppForm.get('location')?.get('openingHours');
}
//by
get openingHoursFormData() {
return <FormArray>this.createAppForm.get('location')?.get('openingHours');
}

你可以用this.headlineFormData代替this.getHeadlineFormData()——注意,使用getter时你不需要写括号。在html中headlineFormData.controls代替getHeadlineFormData().controls-再次看到使用"getter"你不能写圆括号

你的fork stackbliz

最新更新