如何在 FormGroup 中动态生成 FormControls?
How can I generate FormControls dynamically inside a FormGroup?
我从数据库接收到一个对象,其中包含一些具有以下格式的元素:
info = [{
idcentro: "8227",
namecentro: "Centro Paris",
address: "C/ Paris, 127",
dias: [
{
dia: "0",
horafinal: "06:00",
horainicio: "17:00",
salas: [
{
id: 0,
nombre: "sala 1",
intervalos: [
["09:00", "12:30", "10"],
["13:00", "21:30", "20"]
]
}
]
},
{
dia: "1",
horafinal: "09:00",
horainicio: "16:30",
salas: [
{
id: 0,
nombre: "sala 1",
intervalos: [
["09:00", "12:30", "10"]
]
},
{
id: 1,
nombre: "sala 2",
intervalos: [
["09:00", "20:30", "20"]
]
}
]
},
{
dia: "2",
horafinal: "09:00",
horainicio: "20:30",
salas: [
{
id: 0,
nombre: "sala 1",
intervalos: [
["09:00", "12:30", "10"],
["12:45", "18:30", "15"]
]
},
{
id: 1,
nombre: "sala 2",
intervalos: [
["09:00", "20:30", "20"]
]
}
]
}
]
}];
为了使用这些“dias”数组并包含输入以在用户需要时修改每个值,我手动创建了一个 FormGroup,其中包含那些日子中的每一天的 formControl(真实对象最多包含 8 个天)。
this.openingHoursForm = new FormGroup({
day0OpeningTime: new FormControl(""),
day0ClosingTime: new FormControl(""),
day1OpeningTime: new FormControl(""),
day1ClosingTime: new FormControl(""),
day2OpeningTime: new FormControl(""),
day2ClosingTime: new FormControl(""),
day3OpeningTime: new FormControl(""),
day3ClosingTime: new FormControl(""),
day4OpeningTime: new FormControl(""),
day4ClosingTime: new FormControl(""),
day5OpeningTime: new FormControl(""),
day5ClosingTime: new FormControl(""),
day6OpeningTime: new FormControl(""),
day6ClosingTime: new FormControl(""),
day7OpeningTime: new FormControl(""),
day7ClosingTime: new FormControl(""),
day8OpeningTime: new FormControl(""),
day8ClosingTime: new FormControl("")
});
然后,在 HTML 中,我为每个 formControlNames 创建了两个输入:
<div class="dayOpeningHours" title="">
<div>Day 0</div>
<div class="opens">
<label for="">De:
<input class="form-control" type="time" formControlName="day0OpeningTime" name="day0OpeningTime">
</label>
</div>
<div class="closes">
<label for="">A:
<input class="form-control" formControlName="day0ClosingTime" name="day0ClosingTime">
</label>
</div>
</div>
如您所见,这变得非常难以维护。我试图通过遍历 'dias' 数组的每个“dia”来动态创建标记(在 html 中)和 formControlNames(在 ts 中),但我没有取得任何成就。
有没有办法在同一个 formGroup 中生成 HTML 和那些 Form Controls 的声明?我一直在阅读有关 FormArray 和 AbstractControl 的内容,但我无法真正理解如何将其应用到我的代码中。
有人可以帮助我或给我一些提示来找到正确的文档吗?
谢谢
更好的选择是使用 FormArray
。您还可以从 @angular/forms
注入 FormBuilder
见下文
constructor (private fb: FormBuilder) { }
diasForm = this.fb.group({
openingHours: this.fb.array([])
})
get openingHours (): FormArray {
return this.diasForm.get('openingHours') as FormArray;
}
下一个任务是创建表单
假设我们有 dias
作为数组
dias = [
{
dia: "0",
horafinal: "06:00",
horainicio: "17:00",
},
{
dia: "1",
horafinal: "06:00",
horainicio: "17:00",
},
...
]
为简单起见,我删除了其他属性
在ngOnInit
中我们可以设置我们表单的值
ngOnInit() {
this.dias.forEach(dia => {
this.openingHours.push(
this.fb.group({
horafinal: [dia.horafinal, []],
horainicio: [dia.horainicio, []]
})
)
})
}
在Html
<form [formGroup]='diasForm'>
<div formArrayName='openingHours'>
<div *ngFor='let item of openingHours.controls; let i = index'
[formGroupName]='i'>
<input formControlName='horafinal' />
<input formControlName='horainicio' />
</div>
</div>
</form>
以上应该符合我们formGroup的结构
diasForm( [formGroup] ) ---> openingHours(formArray) ---> i ( [formGroup] ) ---> horafinal(formControl)
这样你就可以有一个动态的天数
它是一个大而复杂的对象,但是控制 json 对象的“方式”总是相同的:简单的属性是 FormControl,数组是 FormArrays,我们使用 FormGroup 对控件进行分组。
这么细心,做四个函数来创建表单
createForm(data: any = null) {
data = data || {idcentro: null,namecentro: null,address: null,dias: null};
return new FormGroup({
idcentro: new FormControl(data.idcentro),
namecentro: new FormControl(data.namecentro),
address: new FormControl(data.address),
dias: new FormArray(
data.dias ? data.dias.map(x => this.createFormDias(x)) : []
)
});
}
createFormDias(data: any = null) {
data = data || {dia: null,horafinal: null,horainicio: null,salas: null};
return new FormGroup({
dia: new FormControl(data.dia),
horafinal: new FormControl(data.horafinal),
horainicio: new FormControl(data.horainicio),
salas: new FormArray(
data.salas ? data.salas.map(x => this.createFormSalas(x)) : []
)
});
}
createFormSalas(data: any = null) {
data = data || { id: null, nombre: null, intervalos: null };
return new FormGroup({
id: new FormControl(data.id),
nombre: new FormControl(data.nombre),
intervalos:new FormArray(
data.intervalos?this.createFormIntervalos(data.intervalos):[])
});
}
createFormIntervalos(data:any=null)
{
return data.map(x=>new FormArray(x.map(y=>new FormControl(y))))
}
还有四个函数来获取formArrays
get diasArray()
{
return this.form.get('dias') as FormArray
}
getSalas(index)
{
return this.diasArray.at(index).get('salas') as FormArray
}
getIntervalos(index1,index2)
{
return this.getSalas(index1).at(index2).get('intervalos') as FormArray
}
getHoras(index1,index2,index3)
{
return this.getIntervalos(index1,index2).at(index3) as FormArray
}
要在 .html 中进行控制,您需要考虑何时 FormArray 是 FormGroups 的 FormArray 以及何时是 FormControls 的 FormArray
<form [formGroup]="form">
<div>idcentro:<input formControlName="idcentro" /></div>
<div>namecentro:<input formControlName="namecentro" /></div>
<div>address:<input formControlName="address" /></div>
<div formArrayName="dias">
<div
*ngFor="let grDias of diasArray.controls;let i=index"
[formGroupName]="i"
>
<div>dia:<input formControlName="dia" /></div>
<div>horafinal:<input formControlName="horafinal" /></div>
<div>horainicio:<input formControlName="horainicio" /></div>
<div formArrayName="salas">
<div
*ngFor="let grSalas of getSalas(i).controls;let j=index"
[formGroupName]="j"
>
<div>id:<input formControlName="id" /></div>
<div>nombre:<input formControlName="nombre" /></div>
<div formArrayName="intervalos">
<div
*ngFor="let grIntervalos of getIntervalos(i,j).controls;let k=index"
>
<div [formArrayName]="k">
<div *ngFor="let grHoras of getHoras(i,j,k).controls;let m=index">
<input [formControlName]="m">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
看到我们使用的FormGroup的FormArray
<div formGroupName="nameOfArray">
<div *ngFor="let group of formArray.controls;let i=index" [formGroupName]="i">
..here..
<input formControlName="controlName">
</div>
</div>
还有一个 FormControl 的 FormGroup
<div formGroupName="nameOfArray">
<div *ngFor="let group of formArray.controls;let i=index" >
<input [formControlName]="i">
</div>
</div>
我从数据库接收到一个对象,其中包含一些具有以下格式的元素:
info = [{
idcentro: "8227",
namecentro: "Centro Paris",
address: "C/ Paris, 127",
dias: [
{
dia: "0",
horafinal: "06:00",
horainicio: "17:00",
salas: [
{
id: 0,
nombre: "sala 1",
intervalos: [
["09:00", "12:30", "10"],
["13:00", "21:30", "20"]
]
}
]
},
{
dia: "1",
horafinal: "09:00",
horainicio: "16:30",
salas: [
{
id: 0,
nombre: "sala 1",
intervalos: [
["09:00", "12:30", "10"]
]
},
{
id: 1,
nombre: "sala 2",
intervalos: [
["09:00", "20:30", "20"]
]
}
]
},
{
dia: "2",
horafinal: "09:00",
horainicio: "20:30",
salas: [
{
id: 0,
nombre: "sala 1",
intervalos: [
["09:00", "12:30", "10"],
["12:45", "18:30", "15"]
]
},
{
id: 1,
nombre: "sala 2",
intervalos: [
["09:00", "20:30", "20"]
]
}
]
}
]
}];
为了使用这些“dias”数组并包含输入以在用户需要时修改每个值,我手动创建了一个 FormGroup,其中包含那些日子中的每一天的 formControl(真实对象最多包含 8 个天)。
this.openingHoursForm = new FormGroup({
day0OpeningTime: new FormControl(""),
day0ClosingTime: new FormControl(""),
day1OpeningTime: new FormControl(""),
day1ClosingTime: new FormControl(""),
day2OpeningTime: new FormControl(""),
day2ClosingTime: new FormControl(""),
day3OpeningTime: new FormControl(""),
day3ClosingTime: new FormControl(""),
day4OpeningTime: new FormControl(""),
day4ClosingTime: new FormControl(""),
day5OpeningTime: new FormControl(""),
day5ClosingTime: new FormControl(""),
day6OpeningTime: new FormControl(""),
day6ClosingTime: new FormControl(""),
day7OpeningTime: new FormControl(""),
day7ClosingTime: new FormControl(""),
day8OpeningTime: new FormControl(""),
day8ClosingTime: new FormControl("")
});
然后,在 HTML 中,我为每个 formControlNames 创建了两个输入:
<div class="dayOpeningHours" title="">
<div>Day 0</div>
<div class="opens">
<label for="">De:
<input class="form-control" type="time" formControlName="day0OpeningTime" name="day0OpeningTime">
</label>
</div>
<div class="closes">
<label for="">A:
<input class="form-control" formControlName="day0ClosingTime" name="day0ClosingTime">
</label>
</div>
</div>
如您所见,这变得非常难以维护。我试图通过遍历 'dias' 数组的每个“dia”来动态创建标记(在 html 中)和 formControlNames(在 ts 中),但我没有取得任何成就。
有没有办法在同一个 formGroup 中生成 HTML 和那些 Form Controls 的声明?我一直在阅读有关 FormArray 和 AbstractControl 的内容,但我无法真正理解如何将其应用到我的代码中。
有人可以帮助我或给我一些提示来找到正确的文档吗?
谢谢
更好的选择是使用 FormArray
。您还可以从 @angular/forms
FormBuilder
见下文
constructor (private fb: FormBuilder) { }
diasForm = this.fb.group({
openingHours: this.fb.array([])
})
get openingHours (): FormArray {
return this.diasForm.get('openingHours') as FormArray;
}
下一个任务是创建表单
假设我们有 dias
作为数组
dias = [
{
dia: "0",
horafinal: "06:00",
horainicio: "17:00",
},
{
dia: "1",
horafinal: "06:00",
horainicio: "17:00",
},
...
]
为简单起见,我删除了其他属性
在ngOnInit
中我们可以设置我们表单的值
ngOnInit() {
this.dias.forEach(dia => {
this.openingHours.push(
this.fb.group({
horafinal: [dia.horafinal, []],
horainicio: [dia.horainicio, []]
})
)
})
}
在Html
<form [formGroup]='diasForm'>
<div formArrayName='openingHours'>
<div *ngFor='let item of openingHours.controls; let i = index'
[formGroupName]='i'>
<input formControlName='horafinal' />
<input formControlName='horainicio' />
</div>
</div>
</form>
以上应该符合我们formGroup的结构
diasForm( [formGroup] ) ---> openingHours(formArray) ---> i ( [formGroup] ) ---> horafinal(formControl)
这样你就可以有一个动态的天数
它是一个大而复杂的对象,但是控制 json 对象的“方式”总是相同的:简单的属性是 FormControl,数组是 FormArrays,我们使用 FormGroup 对控件进行分组。
这么细心,做四个函数来创建表单
createForm(data: any = null) {
data = data || {idcentro: null,namecentro: null,address: null,dias: null};
return new FormGroup({
idcentro: new FormControl(data.idcentro),
namecentro: new FormControl(data.namecentro),
address: new FormControl(data.address),
dias: new FormArray(
data.dias ? data.dias.map(x => this.createFormDias(x)) : []
)
});
}
createFormDias(data: any = null) {
data = data || {dia: null,horafinal: null,horainicio: null,salas: null};
return new FormGroup({
dia: new FormControl(data.dia),
horafinal: new FormControl(data.horafinal),
horainicio: new FormControl(data.horainicio),
salas: new FormArray(
data.salas ? data.salas.map(x => this.createFormSalas(x)) : []
)
});
}
createFormSalas(data: any = null) {
data = data || { id: null, nombre: null, intervalos: null };
return new FormGroup({
id: new FormControl(data.id),
nombre: new FormControl(data.nombre),
intervalos:new FormArray(
data.intervalos?this.createFormIntervalos(data.intervalos):[])
});
}
createFormIntervalos(data:any=null)
{
return data.map(x=>new FormArray(x.map(y=>new FormControl(y))))
}
还有四个函数来获取formArrays
get diasArray()
{
return this.form.get('dias') as FormArray
}
getSalas(index)
{
return this.diasArray.at(index).get('salas') as FormArray
}
getIntervalos(index1,index2)
{
return this.getSalas(index1).at(index2).get('intervalos') as FormArray
}
getHoras(index1,index2,index3)
{
return this.getIntervalos(index1,index2).at(index3) as FormArray
}
要在 .html 中进行控制,您需要考虑何时 FormArray 是 FormGroups 的 FormArray 以及何时是 FormControls 的 FormArray
<form [formGroup]="form">
<div>idcentro:<input formControlName="idcentro" /></div>
<div>namecentro:<input formControlName="namecentro" /></div>
<div>address:<input formControlName="address" /></div>
<div formArrayName="dias">
<div
*ngFor="let grDias of diasArray.controls;let i=index"
[formGroupName]="i"
>
<div>dia:<input formControlName="dia" /></div>
<div>horafinal:<input formControlName="horafinal" /></div>
<div>horainicio:<input formControlName="horainicio" /></div>
<div formArrayName="salas">
<div
*ngFor="let grSalas of getSalas(i).controls;let j=index"
[formGroupName]="j"
>
<div>id:<input formControlName="id" /></div>
<div>nombre:<input formControlName="nombre" /></div>
<div formArrayName="intervalos">
<div
*ngFor="let grIntervalos of getIntervalos(i,j).controls;let k=index"
>
<div [formArrayName]="k">
<div *ngFor="let grHoras of getHoras(i,j,k).controls;let m=index">
<input [formControlName]="m">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
看到我们使用的FormGroup的FormArray
<div formGroupName="nameOfArray">
<div *ngFor="let group of formArray.controls;let i=index" [formGroupName]="i">
..here..
<input formControlName="controlName">
</div>
</div>
还有一个 FormControl 的 FormGroup
<div formGroupName="nameOfArray">
<div *ngFor="let group of formArray.controls;let i=index" >
<input [formControlName]="i">
</div>
</div>