¿Cuándo usar FormGroup frente a FormArray?

91

FormGroup :

Un FormGroup agrega los valores de cada FormControl secundario en un objeto, con cada nombre de control como clave.

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

FormArray :

Un FormArray agrega los valores de cada FormControl secundario en una matriz.

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

¿Cuándo se debe usar uno sobre el otro?

jcroll
fuente

Respuestas:

122

FormArray es una variante de FormGroup. La diferencia clave es que sus datos se serializan como una matriz (en lugar de ser serializados como un objeto en el caso de FormGroup). Esto puede ser especialmente útil cuando no sabe cuántos controles estarán presentes dentro del grupo, como formularios dinámicos.

Permítanme intentar explicarlo con un ejemplo rápido. Digamos que tiene un formulario donde captura el pedido de pizza de un cliente. Y colocas un botón para permitirles agregar y eliminar solicitudes especiales. Aquí está 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>

y aquí está la clase de componente que define y maneja solicitudes especiales:

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 ofrece más flexibilidad que FormGroup en el sentido de que es más fácil manipular FormControls usando "push", "insert" y "removeAt" que usando FormGroup's "addControl", "removeControl", "setValue", etc. Los métodos FormArray aseguran que los controles sean debidamente rastreada en la jerarquía del formulario.

espero que esto ayude.

Usman
fuente
4
¿Qué pasa si está intentando editar formularios? ¿Cómo itera y agrega controles?
ctilley79
1
¿Cómo refactorizarías esto en componentes?
Justin
¿Es posible agregar objetos con clave: valor en la matriz de formularios en lugar de solo valores?
Anthony
¿Cómo podemos establecer un nombre de etiqueta de formulario? ¿Hay alguna opción para configurar mientras se inicializa el control de formulario? dado que la forma dinámica no pudimos establecer su valor.
Krishnadas PC
29

Para crear formas reactivas, un padre FormGroupes imprescindible. Esto FormGrouppuede contener además formControls, niño formGroupsoformArray

FormArraypuede contener además una matriz de formControlso a formGroupsí mismo.

¿Cuándo debemos usar formArray?

Lea esta hermosa publicación que explica el uso deformArray

El ejemplo interesante de ese blog es sobre los viajes formGroup

La estructura de los viajes formGroupusando formControly formArrayse vería así:

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

No olvides jugar con esto DEMO y observe el uso de array para citiesy placesde un viaje.

Amit Chigadani
fuente
Explicación corta y dulce.
Kanchan
explicación asombrosa
Taoufik Jabbari
Excelente hermano.
Jalpa
@scopchanov Puede que no tenga mucha explicación con el texto, pero la representación de la estructura del formulario da alguna idea. Avísame si hay algo que podamos agregar para mejorar la respuesta :)
Amit Chigadani
Bueno, si alguien dice "explicación", espero ver exactamente eso. Con todo mi respeto, su respuesta está muy cerca de un "enlace solo respuesta" de acuerdo con las definiciones de SO, porque justo donde se llega al punto, es decir, ¿ Cuándo deberíamos usar formArray? , se proporciona un enlace a una publicación de blog, sin citar ninguna parte significativa de la misma. De hecho, ha publicado algún código, pero nuevamente no hay explicación alguna. Hubiera hecho una gran diferencia si hubiera citado ambas reglas de esta publicación de blog.
scopchanov
5

De: Anton Moiseev Libro "Desarrollo angular con mecanografiado, segunda edición". :

Cuando necesite agregar (o quitar) controles a un formulario mediante programación , use FormArray . Es similar a FormGroup pero tiene una variable de longitud . Mientras que FormGroup representa un formulario completo o un subconjunto fijo de los campos de un formulario , FormArray generalmente representa una colección de controles de formulario que pueden crecer o reducirse .

Por ejemplo, puede usar FormArray para permitir que los usuarios ingresen una cantidad arbitraria de correos electrónicos.

HS Progr
fuente
0

Desde la documentación angular puedes ver que

FormArray es una alternativa a FormGroup para administrar cualquier número de controles sin nombre. Al igual que con las instancias de grupos de formularios, puede insertar y eliminar controles dinámicamente de instancias de matrices de formularios, y el valor de la instancia de matriz de formularios y el estado de validación se calculan a partir de sus controles secundarios. Sin embargo, no necesita definir una clave para cada control por nombre, por lo que esta es una gran opción si no conoce la cantidad de valores secundarios de antemano.

Permítanme mostrarles su ejemplo y tratar de explicarles cómo entiendo esto. Puedes ver la fuente aquí

Imagina un formulario que tiene los siguientes campos

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

Aquí tenemos firstName, lastName, addressy el aliasescampo Todos juntos son el grupo formulario para que envuelven todo en group. Al mismo tiempo, addresses como un subgrupo, así que lo envolvemos en otrogroup (¡puedes mirar la plantilla para una mejor comprensión)! Todos los controles de formulario aquí están keyexcepto aliasesy significa que puede introducir sus valores tanto como desee como una matriz simple usando formBuildermétodos como push.

Así es como lo entiendo, espero que ayude a alguien.

Gh111
fuente