Quando utilizzare FormGroup rispetto a FormArray?


96

FormGroup :

Un FormGroup aggrega i valori di ogni FormControl figlio in un oggetto, con ogni nome di controllo come chiave.

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

FormArray :

Un FormArray aggrega i valori di ogni FormControl figlio in una matrice.

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

Quando dovrebbe essere usato uno sull'altro?

Risposte:


128

FormArray è una variante di FormGroup. La differenza fondamentale è che i suoi dati vengono serializzati come un array (invece di essere serializzati come un oggetto nel caso di FormGroup). Ciò potrebbe essere particolarmente utile quando non sai quanti controlli saranno presenti all'interno del gruppo, come i moduli dinamici.

Vorrei provare a spiegare con un rapido esempio. Supponiamo che tu abbia un modulo in cui acquisisci l'ordine di un cliente per la pizza. E inserisci un pulsante per consentire loro di aggiungere e rimuovere eventuali richieste speciali. Ecco la parte html del componente:

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

ed ecco la classe dei componenti che definisce e gestisce le richieste speciali:

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 una maggiore flessibilità rispetto a FormGroup, nel senso che è più facile manipolare FormControls usando "push", "insert" e "removeAt" piuttosto che usare "addControl", "removeControl", "setValue" di FormGroup ecc. I metodi FormArray assicurano che i controlli siano correttamente tracciato nella gerarchia del modulo.

spero che sia di aiuto.


4
cosa succede se stai cercando di modificare i moduli? Come iterate e aggiungete controlli?
ctilley79

1
Come lo trasformeresti in componenti?
Justin

È possibile aggiungere oggetti con chiave: valore nella matrice del modulo anziché solo valori?
Anthony

Come possiamo impostare un nome per l'etichetta del modulo? c'è qualche opzione da impostare mentre il controllo del modulo è inizializzato? poiché il modulo dinamico non è stato possibile impostarne il valore.
Krishnadas PC

30

Per creare forme reattive, un genitore FormGroupè un must. Questo FormGrouppuò contenere ulteriormente formControls, child formGroupsoformArray

FormArraypuò inoltre contenere un array di formControlso uno formGroupstesso.

Quando dovremmo usare formArray?

Si prega di leggere questo bellissimo post che spiega l'uso diformArray

L'esempio interessante in quel blog riguarda i viaggi formGroup

La struttura dei viaggi formGrouputilizzando formControleformArray sarebbe simile a:

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

Non dimenticare di giocare con questa DEMO e nota l'utilizzo dell'array per citiese placesdi un viaggio.


Breve e dolce spiegazione.
Kanchan

spiegazione sorprendente
Taoufik Jabbari

Ottimo fratello.
jalpa

@scopchanov Potrebbe non avere molte spiegazioni con il testo, ma la rappresentazione della struttura del modulo dà un'idea. Fammi sapere se c'è qualcosa che possiamo aggiungere per migliorare la risposta :)
Amit Chigadani

1
Ebbene, se qualcuno dice "spiegazione", allora mi aspetto di vedere esattamente questo. Con tutto il mio rispetto, la tua risposta è molto vicina a una "risposta solo link" secondo le definizioni SO, perché proprio dove arriva al punto, cioè quando dovremmo usare formArray? , viene fornito un collegamento a un post del blog, senza citarne alcuna parte significativa. Hai effettivamente pubblicato del codice, ma ancora una volta nessuna spiegazione. Avrebbe fatto un'enorme differenza, se avessi citato entrambe le regole da questo post del blog.
scopchanov

6

Da: Anton Moiseev Book "Angular Development with Typescript, Second Edition". :

Quando è necessario aggiungere (o rimuovere) controlli a livello di codice a un form , utilizzare FormArray . È simile a FormGroup ma ha una variabile di lunghezza . Mentre FormGroup rappresenta un intero modulo o un sottoinsieme fisso dei campi di un modulo , FormArray di solito rappresenta una raccolta di controlli del modulo che possono crescere o ridursi .

Ad esempio, potresti utilizzare FormArray per consentire agli utenti di inserire un numero arbitrario di messaggi di posta elettronica.


0

Dalla documentazione angolare puoi vederlo

FormArray è un'alternativa a FormGroup per la gestione di un numero qualsiasi di controlli senza nome. Come con le istanze del gruppo di moduli, puoi inserire e rimuovere dinamicamente i controlli dalle istanze della matrice del modulo e il valore dell'istanza della matrice del modulo e lo stato di convalida vengono calcolati dai relativi controlli figlio. Tuttavia, non è necessario definire una chiave per ogni controllo in base al nome, quindi questa è un'ottima opzione se non si conosce in anticipo il numero di valori figlio.

Lascia che ti mostri il loro esempio e provi a spiegare come lo capisco. Puoi vedere la fonte qui

Immagina che una strega del modulo abbia i seguenti campi

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

Qui abbiamo firstName, lastName, addresse aliasestutto campo insieme siamo gruppo modulo in modo che avvolgiamo tutto group. Allo stesso tempo addressè come un sottogruppo, quindi lo avvolgiamo in un altro group(puoi guardare il modello per una migliore comprensione)! Ogni controllo del modulo qui è keytranne aliasese significa che puoi inserire i valori quanto vuoi come un semplice array usando formBuildermetodi come push.

Questo è come lo capisco, spero che aiuti qualcuno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.