Quand utiliser FormGroup contre FormArray?

91

FormGroup :

Un FormGroup regroupe les valeurs de chaque FormControl enfant en un seul objet, avec chaque nom de contrôle comme clé.

const form = new FormGroup({
  first: new FormControl('Nancy', Validators.minLength(2)),
  last: new FormControl('Drew')
});

FormArray :

Un FormArray agrège les valeurs de chaque FormControl enfant dans un tableau.

const arr = new FormArray([
  new FormControl('Nancy', Validators.minLength(2)),
  new FormControl('Drew')
]);

Quand faut-il utiliser l'un sur l'autre?

jcroll
la source

Réponses:

122

FormArray est une variante de FormGroup. La principale différence est que ses données sont sérialisées en tant que tableau (par opposition à être sérialisées en tant qu'objet dans le cas de FormGroup). Cela peut être particulièrement utile lorsque vous ne savez pas combien de contrôles seront présents dans le groupe, comme les formulaires dynamiques.

Laissez-moi essayer de vous expliquer par un exemple rapide. Disons que vous avez un formulaire dans lequel vous capturez la commande d'un client pour Pizza. Et vous placez un bouton pour leur permettre d'ajouter et de supprimer toute demande spéciale. Voici la partie html du composant:

<section>
  <p>Any special requests?</p>
  <ul formArrayName="specialRequests">
    <li *ngFor="let item of orderForm.controls.specialRequests.controls; let i = index">
      <input type="text" formControlName="{{i}}">
      <button type="button" title="Remove Request" (click)="onRemoveSpecialRequest(i)">Remove</button>
    </li>
  </ul>
  <button type="button" (click)="onAddSpecialRequest()">
    Add a Request
  </button>
</section>

et voici la classe de composant définissant et gérant les demandes spéciales:

constructor () {
  this.orderForm = new FormGroup({
    firstName: new FormControl('Nancy', Validators.minLength(2)),
    lastName: new FormControl('Drew'),
    specialRequests: new FormArray([
      new FormControl(null)
    ])
  });
}

onSubmitForm () {
  console.log(this.orderForm.value);
}

onAddSpecialRequest () {
  this.orderForm.controls
  .specialRequests.push(new FormControl(null));
}

onRemoveSpecialRequest (index) {
  this.orderForm.controls['specialRequests'].removeAt(index);
}

FormArray offre plus de flexibilité que FormGroup dans le sens où il est plus facile de manipuler FormControls en utilisant "push", "insert" et "removeAt" qu'en utilisant "addControl", "removeControl", "setValue", etc. correctement suivi dans la hiérarchie du formulaire.

J'espère que cela t'aides.

Usman
la source
4
et si vous essayez de modifier des formulaires? Comment itérez-vous et ajoutez-vous des contrôles?
ctilley79
1
Comment refactoriser cela en composants?
Justin
Est-il possible d'ajouter des objets avec clé: valeur dans le tableau de formulaire au lieu de seulement des valeurs?
Anthony
Comment définir un nom d'étiquette de formulaire? y a-t-il une option à définir pendant que le contrôle de formulaire est initialisé? puisque la forme dynamique nous n'avons pas pu définir sa valeur.
Krishnadas PC
29

Afin de créer un formulaire réactif, un parent FormGroupest indispensable. Cela FormGrouppeut en outre contenir formControls, enfant formGroupsouformArray

FormArraypeut en outre contenir un tableau de formControlsou un formGrouplui - même.

Quand devrions-nous utiliser formArray?

Veuillez lire ce bel article qui explique l'utilisation deformArray

L'exemple intéressant de ce blog concerne les voyages formGroup

La structure des voyages formGrouputilisant formControlet formArrayressemblerait à quelque chose comme:

this.tripForm = this.fb.group({
    name: [name, Validators.required],
     cities: new FormArray(
       [0] ---> new FormGroup({
           name: new FormControl('', Validators.required),
               places: new FormArray(
                  [0]--> new FormGroup({
                      name: new FormControl('', Validators.required),
                         }),
                      [1]--> new FormGroup({
                         name: new FormControl('', Validators.required),
                      })
                  )
              }), 
       [1] ---> new FormGroup({
           name: new FormControl('', Validators.required),
           places: new FormArray(
               [0]--> new FormGroup({
                   name: new FormControl('', Validators.required),
               }),
               [1]--> new FormGroup({
                   name: new FormControl('', Validators.required),
               })
               )
      }))
})

N'oubliez pas de jouer avec cette DEMO , et notez l'utilisation du tableau pour citieset placesd'un voyage.

Amit Chigadani
la source
Explication courte et douce.
Kanchan
explication incroyable
Taoufik Jabbari
Excellent frère.
jalpa
@scopchanov Cela n'a peut-être pas beaucoup d'explications avec le texte, mais la représentation de la structure du formulaire donne une idée. Faites-moi savoir s'il y a quelque chose que nous pouvons ajouter pour améliorer la réponse :)
Amit Chigadani
Eh bien, si quelqu'un dit «explication», alors je m'attends à voir exactement cela. Avec tout mon respect, votre réponse est très proche d'une "réponse de lien seulement" selon les définitions de SO, parce que là où ça arrive à l' essentiel , c'est-à-dire quand devrions-nous utiliser formArray? , un lien vers un article de blog est fourni, sans en citer une partie significative. Vous avez en effet posté du code, mais encore une fois aucune explication. Cela aurait fait une énorme différence si vous aviez cité les deux règles de ce billet de blog.
scopchanov
5

Tiré de: Livre d'Anton Moiseev «Développement angulaire avec Typescript, deuxième édition». :

Lorsque vous devez ajouter (ou supprimer) par programme des contrôles à un formulaire , utilisez FormArray . Il est similaire à FormGroup mais a une variable de longueur . Alors que FormGroup représente un formulaire entier ou un sous-ensemble fixe des champs d'un formulaire , FormArray représente généralement une collection de contrôles de formulaire qui peuvent augmenter ou diminuer .

Par exemple, vous pouvez utiliser FormArray pour permettre aux utilisateurs de saisir un nombre arbitraire d'e-mails.

Progr HS
la source
0

De la documentation angulaire, vous pouvez voir que

FormArray est une alternative à FormGroup pour gérer n'importe quel nombre de contrôles sans nom. Comme avec les instances de groupe de formulaires, vous pouvez insérer et supprimer dynamiquement des contrôles à partir d'instances de tableau de formulaires, et la valeur de l'instance de tableau de formulaires et l'état de validation sont calculés à partir de ses contrôles enfants. Cependant, vous n'avez pas besoin de définir une clé pour chaque contrôle par son nom, c'est donc une excellente option si vous ne connaissez pas à l'avance le nombre de valeurs enfants.

Laissez-moi vous montrer leur exemple et essayer d'expliquer comment je comprends cela. Vous pouvez voir la source ici

Imaginez un formulaire avec les champs suivants

  profileForm = this.fb.group({
    firstName: ['', Validators.required],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
    aliases: this.fb.array([
      this.fb.control('')
    ])
  });

Ici , nous avons firstName, lastName, addresset aliasesTous les champs ensemble sont un groupe de formulaire pour que nous envelopper tout group. En même temps, addressc'est comme un sous-groupe donc nous l'enveloppons dans un autre group(vous pouvez regarder le modèle pour une meilleure compréhension)! Tous les contrôles de formulaire ici, keysauf aliaseset cela signifie que vous pouvez y insérer des valeurs autant que vous le souhaitez, comme un simple tableau en utilisant des formBuilderméthodes comme push.

C'est comme ça que je le comprends, j'espère que ça aide quelqu'un.

Gh111
la source