Maison  >  Article  >  interface Web  >  Une introduction aux formulaires réactifs en Angular

Une introduction aux formulaires réactifs en Angular

不言
不言original
2018-07-11 14:57:201806parcourir

Cet article présente principalement l'introduction des formulaires réactifs dans Angular. Il a une certaine valeur de référence. Maintenant, je le partage avec vous. Les amis dans le besoin peuvent s'y référer.

Les formulaires réactifs sont dans la classe des composants. Écrivez la logique et les règles de validation, contrairement aux formulaires basés sur un modèle où le contrôle est effectué dans le modèle. Les formulaires réactifs sont flexibles et peuvent être utilisés pour gérer n’importe quel scénario de formulaire complexe. Nous écrivons plus de code de composant et moins de code HTML, ce qui facilite les tests unitaires.

Base de formulaire et interface

Base de formulaire

<form novalidate>
  <label>
    <span>Full name</span>
    <input
      type="text"
      name="name"
      placeholder="Your full name">
  </label>
  <p>
    <label>
      <span>Email address</span>
      <input
        type="email"
        name="email"
        placeholder="Your email address">
    </label>
    <label>
      <span>Confirm address</span>
      <input
        type="email"
        name="confirm"
        placeholder="Confirm your email address">
    </label>
  </p>
  <button type="submit">Sign up</button>
</form>

Les prochaines fonctions que nous souhaitons implémenter sont les suivantes :

  • Valeurs de liaison du nom, de l'e-mail, confirmer les zones de saisie

  • Ajouter une fonction de validation de formulaire à toutes les zones de saisie

  • Afficher les informations sur l'exception de validation

  • Lorsque la vérification du formulaire échoue, la soumission du formulaire n'est pas autorisée

  • Fonction de soumission de formulaire

Interface utilisateur

// signup.interface.ts
export interface User {
  name: string;
  account: {
    email: string;
    confirm: string;
  }
}

ngModule et formulaires réactifs

Avant de continuer à introduire les formulaires réactifs en profondeur, nous devons importer le ReactiveFormsModule dans la bibliothèque @angular/forms dans @NgModule :

import { ReactiveFormsModule } from '@angular/forms';

@NgModule({
  imports: [
    ...,
    ReactiveFormsModule
  ],
  declarations: [...],
  bootstrap: [...]
})
export class AppModule {}
Rappel amical : si vous utilisez des formulaires réactifs, importez ReactiveFormsModule ; si vous utilisez des formulaires basés sur des modèles, importez FormsModule.

Approche réactive

Nous allons créer un SignupFormComponent basé sur le formulaire de base défini ci-dessus :

signup-form.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'signup-form',
  template: `
    <form novalidate>...</form>
  `
})
export class SignupFormComponent {
  constructor() {}
}

Ce Il s'agit d'un composant de base. Avant d'implémenter les fonctions ci-dessus, nous devons présenter les concepts et les utilisations de FormControl, FormGroup et FormBuilder.

FormControl et FormGroup

Introduisons d'abord les concepts de FormControl et FormGroup :

FormControl - Il s'agit d'une classe qui prend en charge un seul contrôle de formulaire et peut être utilisée pour suivre la valeur des contrôles et l’état de validation, en plus de fournir une série d’API publiques.

Exemple d'utilisation :

ngOnInit() {
  this.myControl = new FormControl('');
}
FormGroup - Contient un ensemble d'instances FormControl qui peuvent être utilisées pour suivre la valeur et l'état de validation du groupe FormControl, et fournit également une série d'API publiques .

Exemple d'utilisation :

ngOnInit() {
  this.myGroup = new FormGroup({
    name: new FormControl(''),
    location: new FormControl('')
  });
}

Maintenant que nous avons créé les instances FormControl et FormGroup, voyons comment l'utiliser :

<form novalidate [formGroup]="myGroup">
  Name: <input type="text" formControlName="name">
  Location: <input type="text" formControlName="location">
</form>

Dans ce qui précède Par exemple, nous devons utiliser [formGroup] pour lier l'objet myGroup que nous avons créé et, en plus d'utiliser la directive formControlName, lier le contrôle FormControl que nous avons créé. La structure du formulaire à l'heure actuelle est la suivante :

FormGroup -> 'myGroup'
    FormControl -> 'name'
    FormControl -> 'location'

Implémentation de notre modèle FormGroup

signup.interface.ts

export interface User {
  name: string;
  account: {
    email: string;
    confirm: string;
  }
}

La structure du formulaire correspondante est la suivante :

FormGroup -> 'user'
    FormControl -> 'name'
    FormGroup -> 'account'
        FormControl -> 'email'
        FormControl -> 'confirm'

Oui, nous pouvons créer des collections FormGroup imbriquées ! Mettons à jour le composant (sans les données initiales) :

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

@Component({...})
export class SignupFormComponent implements OnInit {
  user: FormGroup;
  ngOnInit() {
    this.user = new FormGroup({
      name: new FormControl(''),
      account: new FormGroup({
        email: new FormControl(''),
        confirm: new FormControl('')
      })
    });
  }
}

Si nous voulons définir les données initiales, nous pouvons le faire comme dans l'exemple ci-dessus. Normalement, nous obtenons les informations initiales du formulaire via l'interface API fournie par le serveur.

Liaison de notre modèle FormGroup

Maintenant que nous avons instancié le modèle FormGroup, il est temps de se lier à l'élément DOM correspondant. L'exemple spécifique est le suivant :

<form novalidate [formGroup]="user">
  <label>
    <span>Full name</span>
    <input
      type="text"
      placeholder="Your full name"
      formControlName="name">
  </label>
  <p formGroupName="account">
    <label>
      <span>Email address</span>
      <input
        type="email"
        placeholder="Your email address"
        formControlName="email">
    </label>
    <label>
      <span>Confirm address</span>
      <input
        type="email"
        placeholder="Confirm your email address"
        formControlName="confirm">
    </label>
  </p>
  <button type="submit">Sign up</button>
</form>

Maintenant, les informations liées entre les objets FormGroup et FormControl et la structure DOM sont les suivantes :

// JavaScript APIs
FormGroup -> 'user'
    FormControl -> 'name'
    FormGroup -> 'account'
        FormControl -> 'email'
        FormControl -> 'confirm'

// DOM bindings
formGroup -> 'user'
    formControlName -> 'name'
    formGroupName -> 'account'
        formControlName -> 'email'
        formControlName -> 'confirm'

Soumission réactive

Le comme le formulaire basé sur un modèle, nous pouvons gérer la logique de soumission du formulaire via l'attribut de sortie ngSubmit :

<form novalidate (ngSubmit)="onSubmit()" [formGroup]="user">
  ...
</form>

Validation d'erreur réactive

Ensuite, nous ajoutons des règles de validation au formulaire. besoin d'ajouter des règles de validation à partir des validateurs d'importation @angular/forms. Des exemples d'utilisation spécifiques sont les suivants :

ngOnInit() {
  this.user = new FormGroup({
    name: new FormControl('', [Validators.required, Validators.minLength(2)]),
    account: new FormGroup({
      email: new FormControl('', Validators.required),
      confirm: new FormControl('', Validators.required)
    })
  });
}

A travers les exemples ci-dessus, nous pouvons voir que si le contrôle de formulaire contient plusieurs règles de validation, vous pouvez utiliser un tableau pour déclarer plusieurs règles de validation. Si vous n'incluez qu'une seule règle de validation, déclarez-la simplement directement. De cette façon, nous n'avons pas besoin d'ajouter l'attribut requis au contrôle d'entrée dans le modèle. Ajoutons ensuite la fonction permettant de ne pas autoriser la soumission du formulaire lorsque la vérification du formulaire échoue :

<form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user">
  ...
  <button type="submit" [disabled]="user.invalid">Sign up</button>
</form>

La question est alors de savoir comment obtenir les informations de vérification du contrôle du formulaire ? Nous pouvons utiliser la méthode introduite dans les formulaires basés sur des modèles, comme suit :

<form novalidate [formGroup]="user">
  {{ user.controls.name?.errors | json }}
</form>

De plus, nous pouvons également utiliser l'API fournie par l'objet FormGroup pour obtenir les informations d'erreur de la vérification du contrôle du formulaire :

<form novalidate [formGroup]="user">
  {{ user.get('name').errors | json }}
</form>

Jetons maintenant un œil au code complet :

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { User } from './signup.interface';

@Component({
  selector: 'signup-form',
  template: `
    <form novalidate (ngSubmit)="onSubmit(user)" [formGroup]="user">
      <label>
        <span>Full name</span>
        <input type="text" placeholder="Your full name" formControlName="name">
      </label>
      <p class="error" *ngIf="user.get(&#39;name&#39;).hasError(&#39;required&#39;) && 
            user.get(&#39;name&#39;).touched">
        Name is required
      </p>
      <p class="error" *ngIf="user.get(&#39;name&#39;).hasError(&#39;minlength&#39;) && 
            user.get(&#39;name&#39;).touched">
        Minimum of 2 characters
      </p>
      <p formGroupName="account">
        <label>
          <span>Email address</span>
          <input type="email" placeholder="Your email address" formControlName="email">
        </label>
        <p
          class="error"
          *ngIf="user.get(&#39;account&#39;).get(&#39;email&#39;).hasError(&#39;required&#39;) && 
             user.get(&#39;account&#39;).get(&#39;email&#39;).touched">
          Email is required
        </p>
        <label>
          <span>Confirm address</span>
          <input type="email" placeholder="Confirm your email address" 
             formControlName="confirm">
        </label>
        <p
          class="error"
          *ngIf="user.get(&#39;account&#39;).get(&#39;confirm&#39;).hasError(&#39;required&#39;) && 
             user.get(&#39;account&#39;).get(&#39;confirm&#39;).touched">
          Confirming email is required
        </p>
      </p>
      <button type="submit" [disabled]="user.invalid">Sign up</button>
    </form>
  `
})
export class SignupFormComponent implements OnInit {
  user: FormGroup;
  constructor() {}
  ngOnInit() {
    this.user = new FormGroup({
      name: new FormControl('', [Validators.required, Validators.minLength(2)]),
      account: new FormGroup({
        email: new FormControl('', Validators.required),
        confirm: new FormControl('', Validators.required)
      })
    });
  }
  onSubmit({ value, valid }: { value: User, valid: boolean }) {
    console.log(value, valid);
  }
}

La fonction est implémentée, mais la manière de créer l'objet FormGroup est un peu lourde. L'équipe Angular l'est également. conscient de cela, il nous fournit donc FormBuilder pour simplifier l'opération ci-dessus.

Simplifier avec FormBuilder

Nous devons d'abord importer FormBuilder depuis @angular/forms :

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

export class SignupFormComponent implements OnInit {
  user: FormGroup;
  constructor(private fb: FormBuilder) {}
  ...
}

Ensuite, nous utilisons la méthode group() fournie par l'objet FormBuilder pour créer des objets FormGroup et FormControl :

Code avant ajustement (sans FormBuilder) :

ngOnInit() {
  this.user = new FormGroup({
    name: new FormControl('', [Validators.required, Validators.minLength(2)]),
    account: new FormGroup({
      email: new FormControl('', Validators.required),
      confirm: new FormControl('', Validators.required)
    })
  });
}

Code après ajustement (avec FormBuilder) :

ngOnInit() {
  this.user = this.fb.group({
    name: ['', [Validators.required, Validators.minLength(2)]],
    account: this.fb.group({
      email: ['', Validators.required],
      confirm: ['', Validators.required]
    })
  });
}

Comparer Le code avant et après le réglage, cela semble beaucoup plus pratique. À l'heure actuelle, le code complet après la mise à jour est le suivant :

@Component({...})
export class SignupFormComponent implements OnInit {
  user: FormGroup;
  constructor(private fb: FormBuilder) {}
  ngOnInit() {
    this.user = this.fb.group({
      name: ['', [Validators.required, Validators.minLength(2)]],
      account: this.fb.group({
        email: ['', Validators.required],
        confirm: ['', Validators.required]
      })
    });
  }
  onSubmit({ value, valid }: { value: User, valid: boolean }) {
    console.log(value, valid);
  }
}

Ce qui précède est l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez payer. attention au site PHP chinois !

Recommandations associées :

Le contenu de la version d'art-dialog-vue2.0, un plug-in de dialogue basé sur vue.js

La différence entre AngularJs et Angular couramment utilisés méthodes d'écriture d'instructions

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn