Búsqueda de sitios web

Cómo usar formularios reactivos en Angular


Introducción

Angular ofrece dos formas de trabajar con formularios: formularios basados en plantillas y formularios reactivos (también conocidos como formularios basados en modelos). Los formularios basados en plantillas son la forma predeterminada de trabajar con formularios en Angular. Con formularios controlados por plantillas, las directivas de plantilla se utilizan para crear una representación interna del formulario. Con formularios reactivos, crea su propia representación de un formulario en la clase de componente.

Nota: Los formularios reactivos se introdujeron con Angular 2.

Estas son algunas de las ventajas de las formas reactivas:

  • Uso de validadores personalizados
  • Cambiar la validación dinámicamente
  • Adición dinámica de campos de formulario

En este artículo, explorará cómo se pueden aplicar formularios reactivos a una aplicación Angular de ejemplo.

requisitos previos

Si desea seguir este artículo, necesitará:

  • Node.js instalado localmente, lo que puede hacer siguiendo Cómo instalar Node.js y crear un entorno de desarrollo local.

Esta publicación asume que tienes algunos conocimientos básicos de Angular.

Esta publicación también asume que está construyendo a partir de un proyecto Angular nuevo generado por @angular/cli. Puede consultar esta publicación si está comenzando con Angular CLI.

Este tutorial se verificó con Node v15.1.0, npm v6.14.8, @angular/core v11.0.0 y @angular/forms v11 .0.0.

Paso 1: Configuración del proyecto

A los efectos de este tutorial, compilará a partir de un proyecto Angular predeterminado generado con @angular/cli.

  1. npx @angular/cli new angular-reactive-forms-example --style=css --routing=false --skip-tests

Esto configurará un nuevo proyecto Angular con estilos establecidos en \CSS (a diferencia de \Sass, Less o \Stylus), sin enrutamiento y pruebas de omisión.

Navegue al directorio del proyecto recién creado:

  1. cd angular-reactive-forms-example

Para trabajar con formularios reactivos, utilizará el ReactiveFormsModule en lugar del FormsModule.

Abra app.module.ts en su editor de código y agregue ReactiveFormsModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

En este punto, debería tener un nuevo proyecto Angular con ReactiveFormsModule.

Paso 2: agregar un formulario a la plantilla del componente

Con formas reactivas, la lógica se declara completamente en la clase de componente.

Abra app.component.html en su editor de código y agregue las siguientes líneas de código:

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
  </div>
  <button type="submit">Send</button>
</form>

Este código creará un formulario con tres campos: nombre, correo electrónico y mensaje. También habrá un botón enviar con la etiqueta Enviar. Al enviar el formulario, se llamará al método onSubmit(myForm).

Nota: si está utilizando Angular 2.x, también debe agregar la directiva novalidate con la etiqueta de apertura form, ya que Angular anula la validación de HTML5. Con Angular 4+, novalidate se agrega automáticamente detrás de escena.

Vamos a desglosarlo:

  • formGroup: El formulario será tratado como un FormGroup en la clase del componente, por lo que la directiva formGroup permite dar un nombre al formar grupo.
  • ngSubmit: este es el evento que se activará al enviar el formulario.
  • formControlName: cada campo de formulario debe tener una directiva formControlName con un valor que será el nombre utilizado en la clase del componente.

En este punto, debería tener un nuevo proyecto Angular con una plantilla de componente que usa un formulario.

Paso 3: Creación de la clase de componente

A continuación, en la clase de componente, definirá el FormGroup y los FormControl individuales dentro del FormGroup.

Si se proporciona un valor al nueva un FormControl, se utilizará como valor inicial para el campo.

Observe cómo los nombres FormGroup y FormControl son los mismos que se usaron en la plantilla. También observe cómo inicializa el FormGroup en el gancho del ciclo de vida ngOnInit:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  ngOnInit() {
    this.myForm = new FormGroup({
      name: new FormControl('Sammy'),
      email: new FormControl(''),
      message: new FormControl('')
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

A los efectos de este tutorial, el método onSubmit en realidad no comunica los valores del formulario enviado a ningún servicio o servidor externo. Sirve para mostrar cómo puede acceder a la validez del formulario y los valores de FormControl.

En este punto, puede compilar su aplicación y abrirla en un navegador web. Después de ingresar valores para name, email y message y presionar Enviar, el registro de la consola mostrará los valores.

Paso 4: Actualizar la clase de componente para usar FormBuilder

La construcción del formulario ngOnInit se puede reescribir con el ayudante FormBuilder. Esto le permite renunciar a todas las nuevas del grupo de formularios y controles de formulario.

Vuelva a visitar app.component.ts en su editor de código y elimine FormControl y reemplace FormGroup con FormBuilder:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      name: 'Sammy',
      email: '',
      message: ''
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

Este código con FormBuilder reduce la cantidad de código repetitivo para crear un FormGroup.

Paso 5: Actualizar la clase de componente para usar validadores

Agregue la clase Validators a sus importaciones y declare sus controles de formulario con matrices en lugar de simples valores de cadena.

El primer valor en la matriz es el valor del formulario inicial y el segundo valor es para que lo usen los validadores. Observe cómo se pueden usar varios validadores en el mismo control de formulario envolviéndolos en una matriz.

Vuelva a visitar app.component.ts en su editor de código y agregue Validators:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      name: ['Sammy', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      message: ['', [Validators.required, Validators.minLength(15)]],
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

Este código agrega requerido a los campos name, email y message. También garantiza que el valor de email utilice el formato de una dirección de correo electrónico válida. También garantiza que el valor de message tenga al menos 15 caracteres.

Si alguno de estos requisitos de formulario no se cumple, el valor valid será false. Si se cumplen todos estos requisitos de formulario, el valor valid será true.

Paso 6: Acceso al valor y la validez del formulario en la plantilla

En la plantilla, puede acceder al valor y la validez de cada FormControl y al valor y la validez de todo el grupo de formularios como un todo.

Vuelva a visitar app.component.html y use *ngIf para mostrar mensajes de comentarios al usuario si los valores del formulario no son válidos:

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
    <div *ngIf="myForm.get('name').invalid && (myForm.get('name').dirty || myForm.get('name').touched)">
      Please provide a name.
    </div>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
    <div *ngIf="myForm.get('email').invalid && (myForm.get('email').dirty || myForm.get('email').touched)">
      Please provide a valid email address.
    </div>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
    <div *ngIf="myForm.get('message').invalid && (myForm.get('message').dirty || myForm.get('message').touched)">
      Messages must be at least 15 characters long.
    </div>
  </div>
  <button type="submit" [disabled]="myForm.invalid">Send</button>
</form>

Este código comprueba si el usuario ha interactuado con el campo (sucio o tocado). Luego, si el valor no pasa los requisitos de validación, mostrará el mensaje de error. El botón Enviar también se desactivará hasta que se resuelvan todos los problemas con los valores del formulario.

Hay varias formas de recuperar valores de control de formulario. Este ejemplo usa myForm.get(name) que es equivalente a myForm.controls.name. Es posible recuperar información de error con .hasError(requerido) o .errors.required.

Conclusión

En este artículo, exploró cómo se pueden aplicar formularios reactivos a una aplicación Angular de ejemplo. Usaste FormControl, FormGroup, FormBuilder y Validators para construir un formulario de ejemplo con validación. Para funcionalidad adicional, consulte la documentación oficial.

Si desea obtener más información sobre Angular, consulte nuestra página de temas de Angular para ver ejercicios y proyectos de programación.

Artículos relacionados: