国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解Angular Reactive Form 表單驗證

2019-11-19 16:09:21
字體:
來源:轉載
供稿:網友

本文我們將介紹 Reactive Form 表單驗證的相關知識,具體內容如下:

  1. 使用內建的驗證規則
  2. 動態調整驗證規則
  3. 自定義驗證器
  4. 自定義驗證器 (支持參數)
  5. 跨字段驗證

基礎知識

內建驗證規則

Angular 提供了一些內建的 validators,我們可以在 Template-Driven 或 Reactive 表單中使用它們。

目前 Angular 支持的內建 validators 如下:

  1. required - 設置表單控件值是非空的。
  2. email - 設置表單控件值的格式是 email。
  3. minlength - 設置表單控件值的最小長度。
  4. maxlength - 設置表單控件值的最大長度。
  5. pattern - 設置表單控件的值需匹配 pattern 對應的模式。

示例

this.signupForm = this.fb.group({ userName: ['', [Validators.required, Validators.minLength(3)]], email: ['', [Validators.required, Validators.pattern('[a-z0-9._%+_]+@[a-z0-9.-]+')]]});

動態調整驗證規則

myControl.setValidators(Validators.required);myControl.setValidators([Validators.required, Validators.maxLength(6)]);myControl.clearValidators();myControl.updateValueAndValidity();

自定義驗證器

function myCustomValidator(c: AbstractControl):  {[key: string]: boolean} | null { if(somethingIsWrong) {  return { 'myvalidator': true}; } return null;}

自定義驗證器 (支持參數)

function myCustomValidator(param: any): ValidatorFn { return (c: AbstractControl): {[key: string]: boolean} | null {  if(somethingIsWrong) {   return { 'myvalidator': true};  }   return null; }}

跨字段驗證

emailMatcher

function emailMatcher(c: AbstractControl) { let emailControl = c.get('email'); let confirmControl = c.get('confirmEmail'); if (emailControl.pristine || confirmControl.pristine) {  return null; } return emailControl.value === confirmControl.value ? null : { 'match': true };}

emailGroup

ngOnInit(): void { this.signupForm = this.fb.group({  userName: ['', [Validators.required, Validators.minLength(6)]],  emailGroup: this.fb.group({   email: ['', [Validators.required, Validators.email]],   confirmEmail: ['', [Validators.required]],  }, { validator: emailMatcher })});

在介紹表單驗證前,我們來看一下目前頁面的顯示效果:

表單驗證

表單的內建驗證規則,前面章節已經介紹過了,接下來我們來介紹在表單中如何 "動態調整驗證規則" 。

動態調整驗證規則

為了演示 "動態調整驗證規則" 的功能,我新增了兩個控件:

  1. radio - 用于讓用戶設置是否開啟手機登錄。
  2. tel - 當用戶開啟手機登錄功能,用于讓用戶輸入手機號碼。

當用戶開啟手機登錄功能,手機號碼對應控件的驗證規則,必須是必填且格式為合法的手機號碼。當用戶不開啟手機登錄功能時,手機號碼對應控件將不是必填的。

新增 radio 控件

<div class="form-group">  <div class="col-md-offset-1 col-md-8 checkbox">   開啟手機登錄   <label>     <input type="radio" value="1"      formControlName="enableMobile">       是   </label>   <label>     <input type="radio" value="0"      formControlName="enableMobile">       否   </label>  </div></div>

新增 tel 控件

<div class="form-group"  [ngClass]="{'has-error': (mobile.touched || mobile.dirty) && !mobile.valid }">     <label class="col-md-2 control-label"         for="mobileId">手機號碼</label>     <div class="col-md-8">      <input class="form-control"          id="mobileId"          type="text"          placeholder="請輸入手機號碼"          formControlName="mobile"/>      <span class="help-block" *ngIf="(mobile.touched || mobile.dirty)         && mobile.errors">         <span *ngIf="mobile.errors.required">           請輸入手機號碼         </span>         <span *ngIf="mobile.errors.minlength">           手機號碼格式不正確         </span>      </span>     </div></div>

動態調整驗證規則功能

ngOnInit(): void {  ...  this.signupForm.get('enableMobile').valueChanges   .subscribe(value => this.checkMobile(value));}checkMobile(enableMobile: string): void { const mobileControl = this.signupForm.get('mobile');  enableMobile === "1" ?    mobileControl.setValidators([Validators.required,    Validators.pattern('1(3|4|5|7|8)//d{9}')]) :   mobileControl.clearValidators();   mobileControl.updateValueAndValidity();}

介紹完如何動態調整驗證規則,接下來我們來介紹如何 "自定義驗證器"。

自定義驗證器

為了演示 "自定義驗證器" 的功能,我新增了一個控件:

number - 用于讓用戶設置是年齡信息。

當讓用戶手動輸入年齡信息時,我們需要設置一個有效的年齡范圍,比如 (18 - 120)。此時我們就需要通過自定義驗證器來實現上述功能。

新增 number 控件

<div class="form-group"  [ngClass]="{'has-error': (age.touched || age.dirty) && !age.valid }">  <label class="col-md-2 control-label"   for="ageId">年齡</label>   <div class="col-md-8">     <input class="form-control"         id="ageId"         type="number"         placeholder="請輸入年齡"         formControlName="age"/>     <span class="help-block" *ngIf="(age.touched || age.dirty) && age.errors">         <span *ngIf="age.errors.range">           輸入年齡不合法         </span>     </span>   </div></div>

自定義驗證器模板

function myCustomValidator(c: AbstractControl):  {[key: string]: boolean} | null { if(somethingIsWrong) {  return { 'myvalidator': true}; } return null;}

新增 ageValidator 驗證器

function ageValidator(c: AbstractControl): { [key: string]: any } | null { let age = c.value; if (age && (isNaN(age) || age < 20 || age > 120)) {  return { 'range': true, min: 20, max: 120 }; } return null;}

使用 ageValidator 驗證器

ngOnInit(): void { this.signupForm = this.fb.group({  // ...  age: ['', ageValidator] });}

我們的 ageValidator 自定義驗證器,雖然已經實現了。細心的讀者應該會發現,在 ageValidator 驗證器內部,我們寫死了年齡的邊界值 (最小值與最大值)。理想的情況下,應該能夠讓用戶自行設定邊界值。因此接下來,我們來優化一下 ageValidator 驗證器。

自定義驗證器 (支持參數)

自定義驗證器模板 (支持參數)

function myCustomValidator(param: any): ValidatorFn { return (c: AbstractControl): {[key: string]: boolean} | null {  if(somethingIsWrong) {   return { 'myvalidator': true};  }   return null; }}

新增 ageRange 驗證器工廠

function ageRange(min: number, max: number): ValidatorFn { return (c: AbstractControl): { [key: string]: any } | null => {  let age = c.value;  if (age && (isNaN(age) || age < min || age > max)) {   return { 'range': true, min: min, max: max };  }  return null; }}

使用 ageRange 驗證器工廠

ngOnInit(): void { this.signupForm = this.fb.group({  // ...  age: ['', ageRange(20, 120)] });}

介紹完如何自定義驗證器,接下來我們來介紹如何實現 "跨字段驗證" 的功能。

跨字段驗證

在日常生活中,在注冊表單中,經常要讓用戶再次輸入同樣的字段值,比如登錄密碼或郵箱地址的值。針對這種場景,我們就需要驗證兩個控件的輸入值是否一致,這時我們就要引入跨字段驗證的功能。

為了演示 "跨字段驗證" 的功能,我新增了一個控件:

  1. email - 用于讓用戶確認輸入的郵箱地址

新增 email 控件

<label class="col-md-2 control-label"    for="emailId">確認郵箱</label><div class="col-md-8">   <input class="form-control"      id="confirmEmailId"      type="email"      placeholder="請再次輸入郵箱地址"      formControlName="confirmEmail"/>   <span class="help-block" *ngIf="(confirmEmail.touched ||       confirmEmail.dirty)">      <span *ngIf="confirmEmail.errors?.required">        請輸入郵箱地址      </span>      <span *ngIf="!confirmEmail.errors?.required &&         emailGroup.errors?.match">        兩次輸入的郵箱地址不一致      </span>   </span></div>

新增 emailMatcher

function emailMatcher(c: AbstractControl) { let emailControl = c.get('email'); let confirmControl = c.get('confirmEmail'); if (emailControl.pristine || confirmControl.pristine) {  return null; } return emailControl.value === confirmControl.value ? null : { 'match': true };}

新增 emailGroup

ngOnInit(): void { this.signupForm = this.fb.group({  userName: ['', [Validators.required, Validators.minLength(6)]],  emailGroup: this.fb.group({   email: ['', [Validators.required, Validators.email]],   confirmEmail: ['', [Validators.required]],  }, { validator: emailMatcher }),  // ...});

更新模板

<div class="form-group"   formGroupName="emailGroup"   [ngClass]="{'has-error': emailGroup.errors }">     <label class="col-md-2 control-label"         for="emailId">郵箱</label>     <div class="col-md-8">      <input class="form-control"          id="emailId"          type="email"          placeholder="請輸入郵箱地址"          formControlName="email"/>      <span class="help-block" *ngIf="(email.touched || email.dirty) &&         email.errors">         <span *ngIf="email.errors.required">           請輸入郵箱地址         </span>         <span *ngIf="!email.errors.required && email.errors.email">           請輸入有效的郵箱地址         </span>      </span>     </div>     <!--其余部分:請參考"新增email控件"的內容--></div>

上面代碼中,有以下幾個問題需要注意:

  1. Form Group 是可以嵌套使用的。
this.signupForm = this.fb.group({  userName: ['', [Validators.required, Validators.minLength(6)]],  emailGroup: this.fb.group({   email: ['', [Validators.required, Validators.email]],   confirmEmail: ['', [Validators.required]],}, { validator: emailMatcher })

我們通過 formGroupName="groupName" 語法來綁定內嵌的 Form Group。

<div class="form-group" formGroupName="emailGroup"  [ngClass]="{'has-error': emailGroup.errors }">

郵箱不匹配的信息是存在 emailGroup 對象的 errors 屬性中,而不是存在 confirmEmail 對象的 errors 屬性中。

<span *ngIf="!confirmEmail.errors?.required && emailGroup.errors?.match">  兩次輸入的郵箱地址不一致</span>

我有話說

怎么會監聽表單值的變化?

Reactive Form

export class AppComponent { constructor(private fb: FormBuilder) {  this.form = fb.group({   name: 'semlinker',   age: 31  });  this.form.valueChanges.subscribe(data => {   console.log('Form changes', data)  }); }}

Template-driven Form

模板

<form #myForm="ngForm" (ngSubmit)="onSubmit()"> <input type="text"  name="name"   class="form-control"   required     [(ngModel)]="user.name"> <input type="number"    name="age"    class="form-control"    required   [(ngModel)]="user.age"></form>

組件類

class AppComponent implements AfterViewInit { @ViewChild('myForm') form; ngAfterViewInit() {  this.form.control.valueChanges   .debounceTime(500)   .subscribe(values => this.doSomething(values)); }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宕昌县| 申扎县| 开封市| 镇远县| 巩留县| 时尚| 峨眉山市| 浠水县| 台中市| 白山市| 鹤山市| 林甸县| 上杭县| 玉环县| 且末县| 清涧县| 上饶市| 铜鼓县| 房山区| 咸阳市| 邵武市| 光泽县| 惠东县| 德江县| 德清县| 耒阳市| 阿瓦提县| 东源县| 绥江县| 翁牛特旗| 南木林县| 左云县| 高州市| 洪江市| 改则县| 遂宁市| 泊头市| 万载县| 会昌县| 浦北县| 宁远县|