Iterating through a FormArray containing FormGroups with *ngFor

喜欢而已 提交于 2020-08-22 05:42:59

问题


In Ionic 2 I am trying to create a dynamic form which shall display a list of toggle buttons.

To do so I am trying to use a FormArray and relied on the Angular doc and mainly on this post

Based on this, I implemented the following

<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>

Controller

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);
    })

  }

But I get the following error:

ERROR Error: Cannot find control with path: 'sports -> 0 -> '

Here is the content of accountForm

Any idea why ?


回答1:


I don't how/if you can tap into getting the property name of of a dynamically created formcontrol... but you can utilize the list you have instead, from which you are building the formgroups. Then you just have to assign the list you are getting to a local variable, so that you can use it in template.

First off, if you want to use the name of the sport, you need to change your creation the formgroup and use name instead of id:

And I would restructure this a bit, use a getter for the formarray and do:

// choose better name ;)
get formArr() {
  return this.accountForm.get("sports") as FormArray;
}

fb refers to FormBuilder in this case:

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
    })
  );
});

Then as said, you can utilize the list and the index in template, so:

 <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>

Here's a STACKBLITZ with (only) angular



来源:https://stackoverflow.com/questions/44308795/iterating-through-a-formarray-containing-formgroups-with-ngfor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!