Introducere

În acest articol, vom afla despre validări în formulare bazate pe șabloane unghiulare. 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 pentru formularul bazat pe șabloane.

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

  • Se verifică disponibilitatea numelui de utilizator
  • Validarea modelului de parolă
  • Potrivirea parolei introduse în două câmpuri diferite

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

Cum se valideaza formularele bazate pe sabloane unghiulare

Condiții prealabile

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

Cod sursa

Puteți obține 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, iar extensia fișierelor de stil este setată la SCSS. Această comandă va crea proiectul Angular cu numele angular-forme-validare.

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

cd angular-forms-validation
code .

Instalați Bootstrap

Rulați următoarea comandă pentru a instala 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 are în interior două fișiere – customvalidation.service.ts și customvalidation.service.spec.ts. Deschis 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. Această expresie regulată va verifica următoarele patru condiții în parolă:

  • Parola trebuie să aibă minimum opt caractere
  • Ar trebui să aibă cel puțin o literă minusculă
  • Ar trebui să aibă cel puțin o literă mare
  • Ar trebui să aibă 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 șir. 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 funcția 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 modelul de utilizator

Creați un folder nou numit modele în interiorul src/app pliant. Adăugați un fișier nou numit user.ts în interiorul folderului modele. Introduceți următorul cod în user.ts fişier.

export class User {
    public name: string;
    public email: string;
    public username: string;
    public password: string;
    public confirmPassword: string;
}

Creați directive personalizate

Vom crea directive personalizate pentru a implementa validatoare personalizate pentru formulare bazate pe șabloane.

Rulați comanda prezentată mai jos pentru a crea fișierul passwordPattern directivă:

ng g d directivespasswordPattern

Această comandă va crea un folder numit directive care are în interior două fișiere – passwordPattern.directive.ts și passwordPattern.directive.spec.ts. Deschis passwordPattern.directive.ts și puneți următorul cod în interiorul acestuia.

import { Directive } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';

@Directive({
  selector: '[appPasswordPattern]',
  providers: [{ provide: NG_VALIDATORS, useExisting: PasswordPatternDirective, multi: true }]
})
export class PasswordPatternDirective implements Validator {

  constructor(private customValidator: CustomvalidationService) { }

  validate(control: AbstractControl): { [key: string]: any } | null {
    return this.customValidator.patternValidator()(control);
  }
}

Această directivă este utilizată pentru validarea modelului de parolă. Vom implementa interfața Validator pe clasă PasswordPatternDirective. Vom înlocui metoda de validare care acceptă un parametru de tip AbstractControl, acesta este controlul pe care vrem să-l validăm. Vom invoca apoi patternValidator metoda din serviciu.

Rulați comanda prezentată mai jos pentru a crea fișierul matchPassword directivă:

ng g d directivesmatchPassword

Deschis matchPassword.directive.ts și introduceți următorul cod în el:

import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, ValidationErrors, FormGroup } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';

@Directive({
  selector: '[appMatchPassword]',
  providers: [{ provide: NG_VALIDATORS, useExisting: MatchPasswordDirective, multi: true }]
})
export class MatchPasswordDirective implements Validator {
  @Input('appMatchPassword') MatchPassword: string[] = [];

  constructor(private customValidator: CustomvalidationService) { }

  validate(formGroup: FormGroup): ValidationErrors {
    return this.customValidator.MatchPassword(this.MatchPassword[0], this.MatchPassword[1])(formGroup);
  }
}

Această directivă este utilizată pentru a valida dacă parolele introduse în două câmpuri se potrivesc sau nu. Această directivă va accepta o intrare de tipul șirului de șiruri, care conține câmpurile care se potrivesc. Vom înlocui metoda de validare și vom transmite parametrul de tip FormGroup. Vom invoca apoi MatchPassword metoda din serviciu.

Rulați comanda prezentată mai jos pentru a crea fișierul validateUserName directivă:

ng g d directivesvalidateUserName

Deschis validateUserName.directive.ts și introduceți următorul cod în el:

import { Directive, forwardRef } from '@angular/core';
import { Validator, AbstractControl, NG_ASYNC_VALIDATORS } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';
import { Observable } from 'rxjs';

@Directive({
  selector: '[appValidateUserName]',
  providers: [{ provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => ValidateUserNameDirective), multi: true }]

})
export class ValidateUserNameDirective implements Validator {

  constructor(private customValidator: CustomvalidationService) { }

  validate(control: AbstractControl): Promise<{ [key: string]: any }> | Observable<{ [key: string]: any }> {
    return this.customValidator.userNameValidator(control);
  }
}

Această directivă este utilizată pentru a valida disponibilitatea numelui de utilizator. Vom înlocui metoda de validare și vom transmite parametrul de tip AbstractControl. Vom invoca apoi userNameValidator metoda din serviciu. Această metodă va returna o promisiune.

Creați componenta formularului bazată pe șablon

Rulați comanda afișată mai jos pentru a crea componenta de formular bazată pe șablon:

ng g c template-driven-form

Deschis template-driven-form.component.ts și introduceți următorul cod în el:

import { Component } from '@angular/core';
import { User } from '../models/user';

@Component({
  selector: 'app-template-driven-form',
  templateUrl: './template-driven-form.component.html',
  styleUrls: ['./template-driven-form.component.scss']
})
export class TemplateDrivenFormComponent {

  userModal = new User();

  constructor() { }

  onSubmit() {
    alert('Form Submitted succesfully!!!n Check the values in browser console.');
    console.table(this.userModal);
  }
}

Am creat un obiect userModal de tip Utilizator. Vom lega câmpurile formularului cu proprietatea acestui obiect. onSubmit metoda va afișa mesajul de succes pe ecran și va imprima conținutul formularului pe consolă.

Deschis template-driven-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 Template-driven Form</h3>
                </div>
                <div class="card-body">
                    <form class="form" #registerForm="ngForm" [appMatchPassword]="['password', 'confirmPassword']"
                        (ngSubmit)="registerForm.form.valid && onSubmit()" novalidate>
                        <div class=" form-group">
                            <label>Name</label>
                            <input type="text" class="form-control" [(ngModel)]="userModal.name" name="name"
                                #name="ngModel" required>
                            <span class="text-danger"
                                *ngIf="(name.touched || registerForm.submitted) && name.errors?.required">
                                Name is required
                            </span>
                        </div>
                        <div class="form-group">
                            <label>Email</label>
                            <input type="text" class="form-control" [(ngModel)]="userModal.email" name="email"
                                #email="ngModel" required email>
                            <span class="text-danger"
                                *ngIf="(email.touched || registerForm.submitted) && email.errors?.required">
                                Email is required
                            </span>
                            <span class="text-danger" *ngIf="email.touched && email.errors?.email">
                                Enter a valid email address
                            </span>
                        </div>
                        <div class="form-group">
                            <label>User Name</label>
                            <input type="text" class="form-control" [(ngModel)]="userModal.username" name="username"
                                #username="ngModel" appValidateUserName required>
                            <span class="text-danger"
                                *ngIf="(username.touched || registerForm.submitted) && username.errors?.required">
                                User Name is required
                            </span>
                            <span class="text-danger" *ngIf="username.touched && username.errors?.userNameNotAvailable">
                                User Name not available
                            </span>
                        </div>
                        <div class="form-group">
                            <label>Password</label>
                            <input type="password" class="form-control" [(ngModel)]="userModal.password" name="password"
                                #password="ngModel" appPasswordPattern required>
                            <span class="text-danger"
                                *ngIf="(password.touched || registerForm.submitted) && password.errors?.required">
                                Password is required
                            </span>
                            <span class="text-danger" *ngIf="password.touched && 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" [(ngModel)]="userModal.confirmPassword"
                                name="confirmPassword" #confirmPassword="ngModel" required>
                            <span class="text-danger"
                                *ngIf="(confirmPassword.touched || registerForm.submitted) && confirmPassword.errors?.required">
                                Confirm Password is required
                            </span>
                            <span class="text-danger"
                                *ngIf="confirmPassword.touched && 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 un formular bazat pe șabloane ș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 folosi appMatchPassword directivă privind formularul nostru și treceți parola și confirmPassword câmpuri pentru validare. ngModel proprietatea este utilizată pentru a lega controlul formularului la model.

Pentru validarea disponibilității numelui de utilizator vom folosi appValidateUserName directivă privind câmpul nume de utilizator. În mod similar, vom folosi appPasswordPattern directivă privind câmpul de parolă pentru validarea modelului de parolă.

Vom verifica erorile din comenzile formularului și apoi vom afișa mesajul de eroare de validare corespunzător pe ecran.

Creați componenta nav-bar

Rulați comanda prezentată mai jos 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]='["/template-form"]'>Template Form</a>
            </li>
        </ul>
    </div>
</nav>

Aici adăugăm legătura de navigare la componenta formularului bazată pe șabloane.

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

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

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

@NgModule({
  ...    
  imports: [
    ...
    FormsModule,
    RouterModule.forRoot([
      { path: '', component: TemplateDrivenFormComponent },
      { path: 'template-form', component: TemplateDrivenFormComponent }
    ]),
  ],
})

Demo de execuție

Utilizați 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 bazată pe șablon î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 această postare Validarea formularului bazată pe șablon în unghiular și altora le place pe Blogul lui Ankit Sharma.