Saturday, January 18, 2020

Custom Form Validation in Angular

Trong bài đăng này, tôi sẽ chia sẻ cách xây dựng một tùy chỉnh từ trình xác nhận cho các ứng dụng AngularCustom Form Validation in Angular vào Biểu mẫu hướng mẫu hoặc Biểu mẫu phản ứng.
Ở đây, tôi sẽ chứng minh việc xác thực trường nhập số điện thoại, có 10 chữ số.
Dưới đây là hai ảnh chụp màn hình minh họa xác thực của chúng tôi sẽ trông như thế nào:
Validator for Template-Driven Form
Để xác thực trong các biểu mẫu dựa trên mẫu, các chỉ thị được sử dụng, vì vậy, hãy để Lôi đi trước và tạo một chỉ thị xác thực số điện thoại.
Custom Form Validation in Angular

phone-number-validator.ts
import { Directive } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
  selector: '[phoneValidateDirective]',
  providers: [{
    provide: NG_VALIDATORS,
    useExisting: AppPhoneValidateDirective,
    multi: true
  }]
})
export class AppPhoneValidateDirective implements Validator {
  validate(control: AbstractControl) : {[key: string]: any} | null {
    if (control.value && control.value.length != 10) {
      return { 'phoneNumberInvalid': true }; // return object if the validation is not passed.
    }
    return null; // return null if validation is passed.
  }
}
thêm trình xác nhận vào mảng trình xác nhận hiện tại NG_VALIDATORS do Angular cung cấp:
providers: [{
  provide: NG_VALIDATORS,
  useExisting: Your_Class_Name,
  multi: true
}]
Ở đây, Iveve đã tạo ra chỉ thị điện thoại thực hiện Trình xác thực của @ angular / Forms, mà chúng tôi phải cung cấp phương thức thực hiện sau: verifyate (control: AbstractControl) :: {[key: string]: any} | vô giá trị. Trình xác thực này sẽ trả về một đối tượng nếu xác thực không được thông qua đó là {'phoneNumberInvalid': true} và sẽ trả về null nếu xác thực được thông qua.
Angular thêm giá trị trả về của hàm xác thực trong thuộc tính lỗi của FormControl / NgModel. Nếu thuộc tính lỗi của FormControl / NgModel không trống thì biểu mẫu không hợp lệ và nếu thuộc tính lỗi trống thì biểu mẫu hợp lệ.
app.component.html
<div class="form-group col-sm-4">
  <label for="">Phone</label>
  <input type="text" class="form-control" name="phone" [(ngModel)]="phone" [class.is-invalid]="phonengModel.errors?.phoneNumberInvalid && (phonengModel.touched || phonengModel.dirty)" #phonengModel="ngModel" phoneValidateDirective>    <!-- Added directive to validate phone -->
  <span class="invalid-feedback" *ngIf="(phonengModel.touched || phonengModel.dirty) && phonengModel.errors?.phoneNumberInvalid"> <!-- Checked the errors property contains the 'phoneNumberInvalid' property or not which is returned by the validation function -->
      Phone number must be of 10 digit
  </span>
</div>
Validator for Reactive Forms
app.component.ts
import { FormBuilder, AbstractControl } from '@angular/forms';
import { Component, OnInit } from "@angular/core";
@Component({
  selector: 'reactive-form',
  templateUrl: './reactive-form.component.html'
})
export class AppReactiveForm implements OnInit {
  myForm: FormGroup;
  constructor(
    private fb: FormBuilder
  ) {}
  ngOnInit() {
    this.myForm = this.fb.group({
      phone: ['', [ValidatePhone]] // added the function in validators array of form-control
    });
  }
}
function ValidatePhone(control: AbstractControl): {[key: string]: any} | null  {
  if (control.value && control.value.length != 10) {
    return { 'phoneNumberInvalid': true };
  }
  return null;
}
Chúng tôi đang thêm chức năng vào mảng trình xác nhận của FormControl. app.component.html
<form [formGroup]="myForm" novalidate class="needs-validation" (ngSubmit)="saveForm(myForm)">
  <div class="row">
    <div class="form-group col-sm-4">
      <label for="">Password</label>
      <input type="text" class="form-control " formControlName="phone" [class.is-invalid]="(myForm.get('phone').touched || myForm.get('phone').dirty) && myForm.get('password').">
      <span class="invalid-feedback" *ngIf="(myForm.get('password').touched || myForm.get('password').dirty) && myForm.get('password').invalid">
        Password is required
      </span>
    </div>
  </div>
</form>

Combining Both Validators
Chúng tôi có thể kết hợp cả hai trình xác nhận để chúng tôi không lặp lại mã của mình và tuân theo các nguyên tắc DRY (Don lặp lại chính mình):
phone-number-validator.ts
import { Directive } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
export function ValidatePhone(control: AbstractControl): {[key: string]: any} | null  {
    if (control.value && control.value.length != 10) {
        return { 'phoneNumberInvalid': true };
    }
    return null;
}
@Directive({
    selector: '[phone]',
    providers: [{
        provide: NG_VALIDATORS,
        useExisting: AppPhoneValidateDirective,
        multi: true
    }]
})
export class AppPhoneValidateDirective implements Validator {
    validate(control: AbstractControl) : {[key: string]: any} | null {
    return ValidatePhone(control);
    }
}