使用 *ngFor 迭代包含 FormGroups 的 FormArray
Iterating through a FormArray containing FormGroups with *ngFor
在 Ionic 2 中,我正在尝试创建一个显示切换按钮列表的动态表单。
为此,我尝试使用 FormArray 并依赖于 Angular 文档,主要依赖于此
基于此,我实现了以下
<form *ngIf="accountForm" [formGroup]="accountForm">
<ion-list>
<!-- Personal info -->
<ion-list-header padding-top>
Informations personnelles
</ion-list-header>
<ion-item>
<ion-label stacked>Prénom</ion-label>
<ion-input formControlName="firstname" [value]="(user | async)?.info.firstname" type="text"></ion-input>
</ion-item>
<!-- Sport info -->
<ion-list-header padding-top>
Mes préférences sportives
</ion-list-header>
<ion-list formArrayName="sports">
<ion-item *ngFor="let sport of accountForm.controls.sports.controls; let i = index" [formGroupName]="i">
<ion-label>{{sport.name | hashtag}}</ion-label>
<ion-toggle formControlName="{{sport.name}}"></ion-toggle>
</ion-item>
</ion-list>
</ion-list>
</form>
控制器
ionViewDidLoad() {
console.log('MyAccountPage#ionViewDidLoad');
// Retrieve the whole sport list
this.sportList$ = this.dbService.getSportList();
this.sportList$.subscribe(list => {
// Build form
let sportFormArr: FormArray = new FormArray([]);
for (let i=0; i < list.length; i++) {
let fg = new FormGroup({});
fg.addControl(list[i].id, new FormControl(false));
sportFormArr.push(fg);
}
this.accountForm = this.formBuilder.group({
firstname: ['', Validators.compose([Validators.maxLength(30), Validators.pattern('[a-zA-Z ]*'), Validators.required])],
lastname: ['', Validators.compose([Validators.maxLength(30), Validators.pattern('[a-zA-Z ]*'), Validators.required])],
company: [''],
sports: sportFormArr
});
console.log('form ', this.accountForm);
})
}
但我收到以下错误:
ERROR Error: Cannot find control with path: 'sports -> 0 -> '
这里是accountForm的内容
知道为什么吗?
我不知道 how/if 您可以利用获取动态创建的表单控件的 属性 名称...但是您可以利用您拥有的列表,从中构建表单组。然后你只需要将你得到的列表分配给一个局部变量,这样你就可以在模板中使用它。
首先,如果您想使用运动的 name
,您需要更改您创建的表单组并使用 name
而不是 id:
我会稍微重组一下,使用 getter formarray 并执行:
// choose better name ;)
get formArr() {
return this.accountForm.get("sports") as FormArray;
}
fb
指的是 FormBuilder
在这种情况下:
this.accountForm = this.fb.group({
sports: this.fb.array([])
});
// ...........
// don't use any, type your data!
this.list.forEach((item: any, i) => {
this.formArr.push(
this.fb.group({
[this.list[i].name]: false
})
);
});
然后如前所述,您可以利用模板中的列表和索引,所以:
<ion-item *ngFor="let sport of formArr.controls; let i = index" [formGroupName]="i">
<ion-label>{{list[i].name}}</ion-label>
<ion-toggle [formControlName]="list[i].name"></ion-toggle>
</ion-item>
这是一个 STACKBLITZ 和(仅)angular
在 Ionic 2 中,我正在尝试创建一个显示切换按钮列表的动态表单。
为此,我尝试使用 FormArray 并依赖于 Angular 文档,主要依赖于此
基于此,我实现了以下
<form *ngIf="accountForm" [formGroup]="accountForm">
<ion-list>
<!-- Personal info -->
<ion-list-header padding-top>
Informations personnelles
</ion-list-header>
<ion-item>
<ion-label stacked>Prénom</ion-label>
<ion-input formControlName="firstname" [value]="(user | async)?.info.firstname" type="text"></ion-input>
</ion-item>
<!-- Sport info -->
<ion-list-header padding-top>
Mes préférences sportives
</ion-list-header>
<ion-list formArrayName="sports">
<ion-item *ngFor="let sport of accountForm.controls.sports.controls; let i = index" [formGroupName]="i">
<ion-label>{{sport.name | hashtag}}</ion-label>
<ion-toggle formControlName="{{sport.name}}"></ion-toggle>
</ion-item>
</ion-list>
</ion-list>
</form>
控制器
ionViewDidLoad() {
console.log('MyAccountPage#ionViewDidLoad');
// Retrieve the whole sport list
this.sportList$ = this.dbService.getSportList();
this.sportList$.subscribe(list => {
// Build form
let sportFormArr: FormArray = new FormArray([]);
for (let i=0; i < list.length; i++) {
let fg = new FormGroup({});
fg.addControl(list[i].id, new FormControl(false));
sportFormArr.push(fg);
}
this.accountForm = this.formBuilder.group({
firstname: ['', Validators.compose([Validators.maxLength(30), Validators.pattern('[a-zA-Z ]*'), Validators.required])],
lastname: ['', Validators.compose([Validators.maxLength(30), Validators.pattern('[a-zA-Z ]*'), Validators.required])],
company: [''],
sports: sportFormArr
});
console.log('form ', this.accountForm);
})
}
但我收到以下错误:
ERROR Error: Cannot find control with path: 'sports -> 0 -> '
这里是accountForm的内容
知道为什么吗?
我不知道 how/if 您可以利用获取动态创建的表单控件的 属性 名称...但是您可以利用您拥有的列表,从中构建表单组。然后你只需要将你得到的列表分配给一个局部变量,这样你就可以在模板中使用它。
首先,如果您想使用运动的 name
,您需要更改您创建的表单组并使用 name
而不是 id:
我会稍微重组一下,使用 getter formarray 并执行:
// choose better name ;)
get formArr() {
return this.accountForm.get("sports") as FormArray;
}
fb
指的是 FormBuilder
在这种情况下:
this.accountForm = this.fb.group({
sports: this.fb.array([])
});
// ...........
// don't use any, type your data!
this.list.forEach((item: any, i) => {
this.formArr.push(
this.fb.group({
[this.list[i].name]: false
})
);
});
然后如前所述,您可以利用模板中的列表和索引,所以:
<ion-item *ngFor="let sport of formArr.controls; let i = index" [formGroupName]="i">
<ion-label>{{list[i].name}}</ion-label>
<ion-toggle [formControlName]="list[i].name"></ion-toggle>
</ion-item>
这是一个 STACKBLITZ 和(仅)angular