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.

Habilitando x número de controles de matriz de formulario pre-populado con Formulario Reactivo Angular.

Creando una aplicación con Angular y el constructor de formularios reactivos.

Ejemplo de StackBlitz

El formulario está prellenado y dentro del formulario estoy usando “form.array” para construir una lista dinámica de controles basados en los datos. He deshabilitado los campos ya que quiero que mi formulario sea sólo de lectura inicialmente. Tengo un botón que activa “.enable” en los controles, pero como los controles dinámicos están en “form.array”, no estoy seguro de cómo puedo habilitarlos sin especificar todo el valor de índice de los controles.

Archivo ts

public createForm() {
this.service.getmodel().subscribe((response) => {
this.model = response;

  this.form = this.fb.group({
    type: new FormControl({ value: null, disabled: !this.isOwner }),
    items: this.fb.array(
      this.model.items.map((x) =>
        this.buildFields(x)
      )
    ),
  });
});

}

buildFields(x: any): FormGroup {
return new FormGroup({
name: new FormControl({ value: x.name, disabled: !this.isOwner }),
description: new FormControl({
value: x.description,
disabled: !this.isOwner,
}),
code: new FormControl({ value: x.code, disabled: !this.isOwner }),
});
}

enable() {
this.isOwner = true;
const controls = [‘type’, ‘items.description’];
controls.map((x) => {
this.form.get(x).enable({ onlySelf: true });
});
}

Estoy habilitando el control “type” que habilita un campo de entrada de texto para los elementos en “form.array” he añadido sólo “items.description” – aunque sé que esto es incorrecto ya que este valor no existe. Sería algo como “items[0].description” pero el [0] podría ser cualquier valor determinado por la longitud de los datos.

Archivo html




La meta final es habilitar “formControlName = “name/description/code””.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Creando una aplicación con Angular y Reactive forms builder

    Introducción

    En este artículo, discutiremos cómo crear una aplicación con Angular y Reactive forms builder. Nos enfocaremos en un escenario donde prellenaremos un formulario y usaremos form.array para crear una lista dinámica de controles basados en los datos. También mostraremos cómo habilitar los campos del formulario después de que se haya inicializado.

    Ejemplo en Stackblitz

    Hemos creado una aplicación de muestra en StackBlitz para demostrar el proceso. Haga clic aquí para ver el ejemplo.

    Prellenando el formulario

    En nuestro ejemplo, utilizamos formularios reactivos para prellenar el formulario.

    public createForm() {
      this.service.getmodel().subscribe((response) => {
        this.model = response;
    
        this.form = this.fb.group({
          type: new FormControl({ value: null, disabled: !this.isOwner }),
          items: this.fb.array(
            this.model.items.map((x) =>
              this.buildFields(x)
            )
          ),
        });
      });
    }
    
    buildFields(x: any): FormGroup {
      return new FormGroup({
        name: new FormControl({ value: x.name, disabled: !this.isOwner }),
        description: new FormControl({
          value: x.description,
          disabled: !this.isOwner,
        }),
        code: new FormControl({ value: x.code, disabled: !this.isOwner }),
      });
    }
    

    En el código de arriba, se puede ver que al crear el formulario, estamos usando service.getmodel() para obtener los datos para nuestro formulario. Luego usamos fb.group para crear nuestro grupo de formulario, donde asignamos un control type y un control items con una matriz de controles creados con el método buildFields.

    <div *ngif="form">
      <form [formgroup]="form">
        <textarea formcontrolname="type" name="type" #type="" class="form-control" id="type" rows="6"></textarea>
        <div formarrayname="items">
          <div *ngfor="let orgs of form.controls['items']?.controls; let i = index" [formgroupname]="i">
            <input formcontrolname="name" placeholder="Item name">
            <input formcontrolname="description" placeholder="Item description">
            <input formcontrolname="code" placeholder="Item price">
          </div>
          <button type="button" class="btn btn-success" (click)="enable()">
            Enable
          </button>
    
        </div>
      </form>
    
      <!-- <p>{{ form.value.items}}</p> -->
    </div>
    

    Como se puede ver en el código de arriba, hemos creado un formulario html con formGroup llamado form. En el formulario, tenemos un ‘textarea’ con el control type y un campo de entrada con el control items.
     

    Habilitando los campos del formulario

    Por defecto, hemos deshabilitado los campos del formulario, ya que nos interesaba ver una vista de solo lectura.

    buildFields(x: any): FormGroup {
      return new FormGroup({
        name: new FormControl({ value: x.name, disabled: !this.isOwner }),
        description: new FormControl({
          value: x.description,
          disabled: !this.isOwner,
        }),
        code: new FormControl({ value: x.code, disabled: !this.isOwner }),
      });
    }
    

    Cuando el usuario presiona el botón ‘Enable’, debería habilitar todos los controles en el formulario. Como se puede ver en el código a continuación, hemos utilizado la función form.get para obtener los controles denominados ‘type’ e ‘items[0].description’ y los hemos habilitado.

    enable() {
      this.isOwner = true;
      const controls = ['type', 'items[0].description'];
      controls.map((x) => {
        this.form.get(x).enable({ onlySelf: true });
      });
    }
    

    Sin embargo, sabemos que el índice de los elementos puede ser dinámico y, por lo tanto, podemos obtener la longitud de los elementos y luego utilizar ese índice para habilitar todos los elementos en el formulario.

    enableAll() {
      this.isOwner = true;
      const itemsLength = this.form.controls['items'].length;
      for (let i = 0; i < itemsLength; i++) {
        const controls = ['items', i];
        const fields = ['name', 'description', 'code'];
        fields.map((field) => {
          const controlName: string = controls.concat(field).join('.');
          this.form.get(controlName).enable({ onlySelf: true });
        });
      }
      this.form.get('type').enable({ onlySelf: true });
    }
    

    Conclusión

    En este artículo, hemos discutido cómo crear y prellenar un formulario de Angular utilizando Reactive forms builder. También mostramos cómo habilitar campos de formulario dinámicos en un formulario reactivo.

Comments are closed.