es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Agregar campos dinámicamente en un arreglo de formularios dinámicos

Tengo un formulario que tiene una matriz de formulario como esta:

this.myForm = this.fb.group({
  arr: this.fb.array([this.createItem()])
})

createItem() {
  return this.fb.group({
    name: [''],
    pay: [''],
    type: []
  })
}

addItem() {
  this.arr = this.myForm.get('arr') as FormArray;
  this.arr.push(this.createItem());
}

Los controles de tipo son una lista desplegable con los valores de:

types = [
  { id: 10, name: 'A' },
  { id: 20, name: 'B' },
  { id: 30, name: 'C' },
];

Mi pregunta es: si el usuario selecciona el tipo 'A' para un grupo, quiero agregar dos campos más, 'phone' y 'address', y para 'B' y 'C', quiero que el grupo en particular no agregue campos.

Por ejemplo, si el usuario selecciona 'A' para la primera entrada de la matriz de formulario, agregaré los controles 'phone' y 'address' al 'this.fb.group', y si el usuario lo cambia a 'B' o 'C' para esa fila de la matriz, eliminaré esos dos campos.

Me gustaría suscribirme al control de formulario de tipo, verificar el tipo y agregar controles, ¿pero cómo hacerlo?

El stackblitz es https://stackblitz.com/edit/angular6-dynamic-form-array-fmyxvz?file=src%2Fapp%2Fapp.component.html
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para suscribirse al tipo formcontrol y agregar o eliminar campos en función del valor seleccionado, puede utilizar la biblioteca RxJS y suscribirse a los cambios de valor del control de tipo.

    Aquí tienes un ejemplo de implementación basado en el stackblitz proporcionado:

    import { Component } from '@angular/core';
    import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
    import { Subscription } from 'rxjs';
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent {
      myForm: FormGroup;
      arr: FormArray;
      types = [
        { id: 10, name: 'A' },
        { id: 20, name: 'B' },
        { id: 30, name: 'C' },
      ];
      typeSubscription: Subscription;
    
      constructor(private fb: FormBuilder) {}
    
      ngOnInit() {
        this.myForm = this.fb.group({
          arr: this.fb.array([this.createItem()])
        });
        this.arr = this.myForm.get('arr') as FormArray;
        this.typeSubscription = this.arr.at(0).get('type').valueChanges.subscribe(value => {
          this.togglePhoneAndAddress(value, this.arr.at(0));
        });
      }
    
      togglePhoneAndAddress(typeId: number, group: FormGroup) {
        if (typeId === 10) {
          group.addControl('phone', this.fb.control(''));
          group.addControl('address', this.fb.control(''));
        } else {
          group.removeControl('phone');
          group.removeControl('address');
        }
      }
    
      createItem(): FormGroup {
        return this.fb.group({
          name: [''],
          pay: [''],
          type: []
        })
      }
    
      addItem() {
        this.arr.push(this.createItem());
        const index = this.arr.length - 1;
        this.typeSubscription = this.arr.at(index).get('type').valueChanges.subscribe(value => {
          this.togglePhoneAndAddress(value, this.arr.at(index));
        });
      }
    
      ngOnDestroy() {
        this.typeSubscription.unsubscribe();
      }
    }
    

    En el método ngOnInit, nos suscribimos a los cambios de valor del control de tipo del primer grupo en el array y llamamos al método togglePhoneAndAddress para agregar o eliminar los controles de teléfono y dirección según el tipo seleccionado. Almacenamos la suscripción en una variable para luego cancelarla y evitar fugas de memoria.

    En el método togglePhoneAndAddress, agregamos o eliminamos los controles de teléfono y dirección según el tipo seleccionado. Pasamos el grupo y typeId como argumentos para hacer que el método sea reutilizable.

    En el método addItem, agregamos un nuevo grupo al array, nos suscribimos a los cambios de valor del control de tipo para el nuevo grupo y llamamos al método togglePhoneAndAddress.

    En el método ngOnDestroy, cancelamos la suscripción a typeSubscription para evitar fugas de memoria.

Comments are closed.