Как правильно использовать FormGroup с вложенными данными в угловых реактивных формах

#angular-reactive-forms #formarray #reactive-forms #form-control #formgroups

#formarray #угловые реактивные формы #управление формой #formgroups

Вопрос:

Я новичок в угловых и реактивных формах.

У меня есть таблица с некоторыми элементами формы, и я пытаюсь использовать реактивные формы для сохранения данных. Я смог зациклить и отобразить вложенное поведение json, но не смог должным образом связать массив форм и его элементы управления.

formControlName неправильно зацикливается и неправильно применяется к флажку и вводимому тексту.

app.component.ts

 this.userData.forEach((item)=>{
  item.info.forEach((info)=> {
    const temp = new FormGroup({
      'active': new FormControl(info.active),
      'remarks': new FormControl(info.remarks),
      'id': new FormControl(item.id),
      'name': new FormControl(info.name),
      'number': new FormControl(info.number),
      'group': new FormControl(item.group)
    });

    (<FormArray>this.userForm.controls['userDetails']).push(temp);
  });
});
 

app.component.html

 <div>
<h3>My Form</h3> 
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
    <table class="table">
        <thead>
            
        </thead>
        <tbody formArrayName="userDetails">
            <ng-container *ngFor="let item of userData; let i = index" formGroupName="{{ i }}">
                <tr>
                    <td colspan="5">
                        {{item.group}}
                    </td>
                </tr>
                <tr *ngFor="let info of item.info">
                    <td>
                        <input type="checkbox" formControlName="active">
                    </td>
                    <td>
                        {{info.id}}
                    </td>
                    <td>
                        {{info.name}}
                    </td>
                    <td>
                        {{info.number}}
                    </td>
                    <td>
                        <input type="text" formControlName="remarks">
                    </td>
                </tr>
            </ng-container>
        </tbody>
    </table>
    <div>
        <button class="btn btn-primary" type="submit">Save</button>
    </div>
</form>
</div>
 

данные

 userData = [
{
  "id": 123,
  "group": "A Group",
  "info": [
    {
      'name': "John Smith",
      'number': "789345612",
      'remarks': "Attended Last Session",
      'active': true
    },
    {
      'name': "Bob Mathers",
      'number': "987345120",
      'remarks': "",
      'active': false
    },
    {
      'name': "Steve Kieth",
      'number': "707549120",
      'remarks': "",
      'active': false
    }
  ]
},
{
  "id": 456,
  "group": "B Group",
  "info": [
    {
      'name': "Mia Anne P",
      'number': "880345009",
      'remarks': "",
      'active': false
    },
    {
      'name': "Mathew C Brady",
      'number': "7086183092",
      'remarks': "No Show",
      'active': false
    }
  ]
},
{
  "id": 789,
  "group": "C Group",
  "info": [
    {
      'name': "Stanley Jones",
      'number': "961096478",
      'remarks': "",
      'active': false
    },
    {
      'name': "Gina Qazyt",
      'number': "767654730",
      'remarks': "Arrived Late",
      'active': false
    }
  ]
}
 

]

Как вы можете видеть на скриншоте ниже, активные данные json и поле примечания не совпадают с данными формы

введите описание изображения здесь

Я пробовал размещать

 formGroupName="{{ i }}" and i = index 
 

во втором цикле, но затем formControlName=»active» применяется к каждой первой строке группы

Ответ №1:

Не знаю, действительно ли это ваше требование. Основываясь на вашем выводе, я организовал следующее FormGroup . Вот как я бы это сделал. Хотелось бы также увидеть ответы других.

app.component.ts

 userForm: FormGroup = new FormGroup({ userGroups: new FormArray([]) });

---

this.userData.forEach(
  (item) => {

    const userGroup = new FormGroup({
      id: new FormControl(item.id),
      group: new FormControl(item.group),
      userDetails: new FormArray([])
    });

    item.info.forEach((info) => {
      const userDetail = new FormGroup({
        name: new FormControl(info.name),
        number: new FormControl(info.number),
        remarks: new FormControl(info.remarks),
        active: new FormControl(info.active)
      });
      (userGroup.controls.userDetails as FormArray).push(userDetail);
    });

    (this.userForm.controls.userGroups as FormArray).push(userGroup);
  }
);
 

app.component.html

 <div>
  <h3>My Form</h3>
  <form [formGroup]="userForm" (ngSubmit)="onSubmit(userForm.value)">
    <table class="table">
      <thead>

      </thead>
      <tbody formArrayName="userGroups">
        <ng-container *ngFor="let item of userData; let i = index" formGroupName="{{ i }}">
          <tr>
            <td colspan="5">
              {{item.group}}
            </td>
          </tr>
          <div formArrayName="userDetails">
            <tr *ngFor="let info of item.info; let j = index" formGroupName="{{ j }}">
              <td>
                <input type="checkbox" formControlName="active">
              </td>
              <td>
                {{info.id}}
              </td>
              <td>
                {{info.name}}
              </td>
              <td>
                {{info.number}}
              </td>
              <td>
                <input type="text" formControlName="remarks">
              </td>
            </tr>
          </div>
        </ng-container>
      </tbody>
    </table>
    <div>
      <button class="btn btn-primary" type="submit">Save</button>
    </div>
  </form>
</div>