web-dev-qa-db-fra.com

Angular 5 - Contrôle de formulaire avec des objets

Je travaille actuellement sur une application Angular soutenue par Django.

Une partie de l'application est qu'elle doit afficher une liste de membres. Le tableau des membres ressemble un peu à ceci:

[
  {
    name: 'John Smith',
    id: 3,
    score_set: [...]
  },
  {
    name: 'Jane Doe',
    id: 7,
    score_set: [...]
  },
  {
    name: 'Bill Appleseed',
    id: 3,
    score_set: [...]
  },
  {
    name: 'Bob Lee',
    id: 3,
    score_set: [...]
  }
]

Je l'ai fait fonctionner, mais j'avais également besoin que l'utilisateur puisse modifier les noms de ces membres. J'ai essayé d'utiliser des formulaires réactifs pour que cela fonctionne:

Tout d'abord, j'ai créé un FormGroup composé d'un seul FormArray. Ce FormArray contenait essentiellement tous les objets membres:

this.form = this.fb.group({
  roster: this.fb.array(this.members.map((elem) => [elem, Validators.required]))
});

Ensuite, j'ai écrit le modèle du composant:

<form>
  <div [formGroup]="form">
    <div formArrayName="roster">
      <div *ngFor="let control of form.controls.roster.controls">
        <div class="form-group">
          <input class="form-control" [formControl]="control" placeholder="Enter name">
        </div>
      </div>
    </div>
  </div>
</form>

Mais au lieu d'afficher la propriété name de chaque membre, il essaie simplement d'afficher l'objet entier, ce qui rend [Object object]. Existe-t-il un moyen de configurer chaque FormControl pour utiliser la propriété name comme valeur?

Je le veux pour que seul le nom soit affiché dans le <input>, et lorsque l'utilisateur modifie le <input> il met à jour la propriété name de l'objet, tout en conservant toutes les autres propriétés.

Toute aide serait appréciée!

10
Oliver Ni

Puisque vous souhaitez conserver l'objet complet, vous devrez créer formGroups, comme ceci:

interface Member {
  id: number;
  name: string;
}

ngOnInit(): void {
  this.formGroup = this.formBuilder.group({
    roster: this.formBuilder.array(this.members.map(elem => this.createMemberGroup(elem)))
  });
}

createMemberGroup(member: Member): FormGroup {
  return this.formBuilder.group({
    ...member,
    name: [member.name, Validators.required]
  });
}

HTML:

<form class="container pt-2" [formGroup]="formGroup">
  <div formArrayName="roster">
    <div 
      [formGroupName]="i" 
      *ngFor="let control of formGroup.get('roster').controls; index as i">
      <div class="form-group">
        <input 
          class="form-control" 
          formControlName="name" 
          placeholder="Enter name" 
          [class.is-invalid]="control.invalid">
        <small class="text-danger" *ngIf="control.invalid">Required</small>
      </div>
    </div>
  </div>
</form>

[~ # ~] démo [~ # ~]

13
developer033