Introducere

În acest articol, vom afla despre validări în forme reactive în Angular. Vom crea un formular simplu de înregistrare a utilizatorului și vom implementa câteva validări încorporate pe acesta. Împreună cu validările încorporate, vom implementa și câteva validări personalizate în forma reactivă.

Vom lua în considerare următoarele validări personalizate pentru această demonstrație:

  • Verificați disponibilitatea numelui de utilizator
  • Validarea modelului de parolă
  • Potriviți parola introdusă în două câmpuri diferite

Aruncați o privire asupra aplicației în acțiune.

Cum se valideaza formele reactive unghiulare

Condiții prealabile

  • Instalați codul Visual Studio de la Aici
  • Instalați cea mai recentă versiune a Angular CLI de la Aici

Cod sursa

Obțineți codul sursă de la GitHub.

Creați aplicația Angular

Navigați la folderul în care doriți să creați fișierul de proiect. Deschideți o fereastră de comandă și rulați comanda prezentată mai jos:

ng new angular-forms-validation --routing=false --style=scss

Specificăm comanda pentru a crea o nouă aplicație Angular. Opțiunea de a crea modulul de rutare este setată la fals și extensia fișierelor de stil este setată la scss. Această comandă va crea proiectul Angular cu numele angular-forms-validation.

Schimbați directoarele în noul proiect și deschideți proiectul în VS Code folosind setul de comenzi prezentat mai jos:

cd angular-forms-validation 
code .

Instalați Bootstrap

Rulați următoarea comandă pentru a instala biblioteca Bootstrap:

npm install bootstrap --save

Adăugați următoarea definiție de import în styles.scss fişier:

@import "~bootstrap/dist/css/bootstrap.css";

Creați serviciul de validare

Rulați următoarea comandă pentru a crea un serviciu nou:

ng g s servicescustomvalidation

Această comandă va crea un folder numit servicii care conține două fișiere – customvalidation.service.ts și customvalidation.service.spec.ts. Deschide customvalidation.service.ts și introduceți următorul cod în el:

import { Injectable } from '@angular/core';
import { ValidatorFn, AbstractControl } from '@angular/forms';
import { FormGroup } from '@angular/forms';

@Injectable({
  providedIn: 'root'
})
export class CustomvalidationService {

  patternValidator(): ValidatorFn {
    return (control: AbstractControl): { [key: string]: any } => {
      if (!control.value) {
        return null;
      }
      const regex = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$');
      const valid = regex.test(control.value);
      return valid ? null : { invalidPassword: true };
    };
  }

  MatchPassword(password: string, confirmPassword: string) {
    return (formGroup: FormGroup) => {
      const passwordControl = formGroup.controls[password];
      const confirmPasswordControl = formGroup.controls[confirmPassword];

      if (!passwordControl || !confirmPasswordControl) {
        return null;
      }

      if (confirmPasswordControl.errors && !confirmPasswordControl.errors.passwordMismatch) {
        return null;
      }

      if (passwordControl.value !== confirmPasswordControl.value) {
        confirmPasswordControl.setErrors({ passwordMismatch: true });
      } else {
        confirmPasswordControl.setErrors(null);
      }
    }
  }

  userNameValidator(userControl: AbstractControl) {
    return new Promise(resolve => {
      setTimeout(() => {
        if (this.validateUserName(userControl.value)) {
          resolve({ userNameNotAvailable: true });
        } else {
          resolve(null);
        }
      }, 1000);
    });
  }

  validateUserName(userName: string) {
    const UserList = ['ankit', 'admin', 'user', 'superuser'];
    return (UserList.indexOf(userName) > -1);
  }
}

Metoda patternValidator este folosit pentru a valida modelul de parolă din formularul nostru. Parametrul pentru această metodă este de tip AbstractControl care este o clasă de bază pentru FormControl.

Vom folosi o expresie regulată pentru a valida parola. Vom valida următoarele patru condiții folosind expresia regulată:

  • Parola trebuie să aibă minimum opt caractere.
  • Are cel puțin o literă minusculă.
  • Are cel puțin o literă mare.
  • Are cel puțin un număr.

Dacă parola nu reușește verificarea regex, vom seta invalidPassword proprietate la adevărat.

Metoda MatchPassword este folosit pentru a compara parolele din două câmpuri. Această metodă acceptă doi parametri de tip string. Acești parametri reprezintă numele câmpurilor care trebuie potrivite. Vom primi FormControl pentru aceste două câmpuri și apoi potriviți valorile din ele. Dacă valorile nu se potrivesc, vom seta passwordMismatch proprietate la adevărat.

Metoda userNameValidator este folosit pentru a verifica dacă numele de utilizator este deja luat sau nu. Această metodă acceptă un parametru de tip AbstractControl. Vom verifica dacă valoarea acestui câmp este prezentă într-o matrice statică, UserList. Dacă valoarea introdusă de utilizator este deja prezentă, vom seta valoarea userNameNotAvailable proprietate la adevărat.

Folosim setTimeout pentru a invoca această verificare la fiecare două secunde. Acest lucru vă va asigura că eroarea va fi aruncată după două secunde de la momentul în care utilizatorul încetează să tastați în câmp.

Din simplitatea acestui articol, folosim o matrice statică pentru a căuta disponibilitatea numelor de utilizator. În mod ideal, ar trebui să fie un apel de serviciu către server pentru a căuta valoarea într-o bază de date.

Creați componenta de formă reactivă

Rulați următoarea comandă pentru a crea componenta de formă reactivă:

ng g c reactive-form

Deschis reactive-form.component.ts și introduceți următorul cod:

import { Component, OnInit } from '@angular/core';
import { Validators, FormGroup, FormBuilder } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';

@Component({
  selector: 'app-reactive-form',
  templateUrl: './reactive-form.component.html',
  styleUrls: ['./reactive-form.component.scss']
})
export class ReactiveFormComponent implements OnInit {

  registerForm: FormGroup;
  submitted = false;

  constructor(
    private fb: FormBuilder,
    private customValidator: CustomvalidationService
  ) { }

  ngOnInit() {
    this.registerForm = this.fb.group({
      name: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      username: ['', [Validators.required], this.customValidator.userNameValidator.bind(this.customValidator)],
      password: ['', Validators.compose([Validators.required, this.customValidator.patternValidator()])],
      confirmPassword: ['', [Validators.required]],
    },
      {
        validator: this.customValidator.MatchPassword('password', 'confirmPassword'),
      }
    );
  }

  get registerFormControl() {
    return this.registerForm.controls;
  }

  onSubmit() {
    this.submitted = true;
    if (this.registerForm.valid) {
      alert('Form Submitted succesfully!!!n Check the values in browser console.');
      console.table(this.registerForm.value);
    }
  }
}

Vom crea o variabilă registerForm de tip FormGroup. În ngOnInit metoda, vom seta comenzile pentru formular folosind FormBuilder clasă. Toate câmpurile sunt setate ca un câmp obligatoriu pentru acest formular. Vom invoca userNameValidator metoda serviciului folosind funcția de legare.

Pentru câmpul de parolă, vom folosi metoda compune pentru a fuziona în mai mulți validatori într-o singură funcție. Vom invoca, de asemenea, MatchPassword metoda și treceți numele password și confirmPassword controalele formularului ca parametri.

registerFormControl proprietatea va returna comenzile formularului. onSubmit metoda va imprima conținutul formularului pe consolă dacă formularul este valid și trimis cu succes.

Deschis reactive-form.component.html și introduceți următorul cod:

<div class="container">
    <div class="row">
        <div class="col-md-8 mx-auto">
            <div class="card">
                <div class="card-header">
                    <h3>Angular Reactive Form</h3>
                </div>
                <div class="card-body">
                    <form class="form" [formGroup]="registerForm" (ngSubmit)="onSubmit()">
                        <div class="form-group">
                            <label>Name</label>
                            <input type="text" class="form-control" formControlName="name">
                            <span class="text-danger"
                                *ngIf="(registerFormControl.name.touched || submitted) && registerFormControl.name.errors?.required">
                                Name is required
                            </span>
                        </div>
                        <div class="form-group">
                            <label>Email</label>
                            <input type="text" class="form-control" formControlName="email">
                            <span class="text-danger"
                                *ngIf="(registerFormControl.email.touched || submitted) && registerFormControl.email.errors?.required">
                                Email is required
                            </span>
                            <span class="text-danger"
                                *ngIf="registerFormControl.email.touched && registerFormControl.email.errors?.email">
                                Enter a valid email address
                            </span>
                        </div>
                        <div class="form-group">
                            <label>User Name</label>
                            <input type="text" class="form-control" formControlName="username">
                            <span class="text-danger"
                                *ngIf="(registerFormControl.username.touched || submitted) && registerFormControl.username.errors?.required">
                                User Name is required
                            </span>
                            <span class="text-danger"
                                *ngIf="registerFormControl.username.touched && registerFormControl.username.errors?.userNameNotAvailable">
                                User Name is not available
                            </span>
                        </div>
                        <div class="form-group">
                            <label>Password</label>
                            <input type="password" class="form-control" formControlName="password">
                            <span class="text-danger"
                                *ngIf="(registerFormControl.password.touched || submitted) && registerFormControl.password.errors?.required">
                                Password is required
                            </span>
                            <span class="text-danger"
                                *ngIf="registerFormControl.password.touched && registerFormControl.password.errors?.invalidPassword">
                                Password should have minimum 8 characters, at least 1 uppercase letter, 1 lowercase
                                letter and 1 number
                            </span>
                        </div>
                        <div class="form-group">
                            <label>Confirm Password</label>
                            <input type="password" class="form-control" formControlName="confirmPassword">
                            <span class="text-danger"
                                *ngIf="(registerFormControl.confirmPassword.touched || submitted)&& registerFormControl.confirmPassword.errors?.required">
                                Confirm Password is required
                            </span>
                            <span class="text-danger"
                                *ngIf="registerFormControl.confirmPassword.touched && registerFormControl.confirmPassword.errors?.passwordMismatch">
                                Passwords doesnot match
                            </span>
                        </div>
                        <div class="form-group">
                            <button type="submit" class="btn btn-success">Register</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

Vom crea o formă reactivă și vom folosi cardul Bootstrap pentru stil. Antetul cardului va conține un titlu, în timp ce corpul cardului va avea câmpurile formularului. Vom lega formGroup proprietate a <form> etichetați numele formularului nostru care este registerForm. onSubmit metoda va fi invocată la trimiterea formularului. De asemenea, vom lega formControlName proprietății fiecărui câmp de intrare pentru numele de control al nostru FormGroup. Vom verifica erori în comenzile formularului și apoi vom afișa mesajul de eroare de validare corespunzător pe ecran.

Creați componenta nav-bar

Rulați următoarea comandă pentru a crea componenta nav-bar:

ng g c nav-bar

Deschis nav-bar.component.html și introduceți următorul cod în el:

<nav class="navbar navbar-expand-sm navbar-dark bg-dark fixed-top">
    <a class="navbar-brand" [routerLink]='["/"]'>Form Validation Demo</a>
    <div class="collapse navbar-collapse">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item">
                <a class="nav-link" [routerLink]='["/reactive-form"]'>Reactive Form</a>
            </li>
        </ul>
    </div>
</nav>

Adăugăm linkul de navigare la componenta formularului reactiv din bara de navigație.

Actualizați componenta aplicației

Deschide app.component.html și introduceți următorul cod în el:

<app-nav-bar></app-nav-bar>
<div class="container">
  <router-outlet></router-outlet>
</div>

Actualizați modulul App

Adăugați următorul cod în app.module.ts fişier. Vom importa modulul de formulare și vom defini rutare pentru aplicația noastră. Vă puteți referi la GitHub pentru codul sursă complet al acestui fișier.

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

@NgModule({
  ...    
  imports: [
    ...
    ReactiveFormsModule,
    RouterModule.forRoot([
      { path: '', component: ReactiveFormComponent },
      { path: 'reactive-form', component: ReactiveFormComponent }
    ]),
  ],
})

Demo de execuție

Vom folosi următoarea comandă pentru a porni serverul web:

ng serve -o

Această comandă va lansa aplicația în browserul dvs. implicit la http://localhost:4200/. Puteți efectua toate validările de formulare pe care le-am discutat aici.

Această aplicație este găzduită și la https://ng-forms-validation.herokuapp.com/. Navigați la link și jucați-vă cu el pentru o mai bună înțelegere.

rezumat

Am creat un exemplu de formular de înregistrare a utilizatorului utilizând abordarea formularului reactiv în Angular. Am implementat validările încorporate, precum și validările personalizate ale formularului. Biblioteca Bootstrap este utilizată pentru a stiliza formularul.

Obțineți codul sursă de la GitHub și joacă-te cu el pentru o mai bună înțelegere.

Vezi si

Puteți găsi alte postări precum Validarea formei reactive în unghiular pe Blogul lui Ankit Sharma.