欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Angular在模板驅(qū)動表單中自定義校驗器的方法

 更新時間:2017年08月09日 08:27:17   投稿:mrr  
本章介紹的是如何對模板驅(qū)動表單創(chuàng)建自定義校驗器,它相比較響應式表單自定義校驗器略為復雜一些。接下來通過本文給大家分享Angular在模板驅(qū)動表單中自定義校驗器的方法,感興趣的朋友一起看看吧

引言

模板驅(qū)動表單相比較響應式表單可以少更少的代碼做同樣的事情,可也損失了自由度與更易測試,當然很多人并不在乎啦。

所以我相信很多人在編寫Angular不自由自主去更傾向于模板驅(qū)動表單的寫法。

表單最核心的是校驗體驗,在Angular中簡直就是發(fā)揮到了極致,比如:required、min、max、pattern 等,這些原本是HTML DOM元素中的表述,而Angular默認實現(xiàn)了一整套的校驗指令,比如:required 對應 RequiredValidator。

然后很多時候我們需要一些特殊的校驗,比如:數(shù)據(jù)比較、遠程校驗等。那在模板驅(qū)動表單風格中我們要如何優(yōu)雅的實現(xiàn)這樣一個校驗器呢?

一、Angular是如何校驗?

一般在編寫一個手機文本框可能是這樣:

<input [(ngModel)]="user.mobile" #mobile="ngModel" autocomplete="off" type="tel" class="form-control" name="mobile" required maxlength="11">
<div *ngIf="mobile.errors">
  <p *ngIf="mobile.errors.required">手機號必填</p>
  <p *ngIf="mobile.errors.pattern">手機號格式不正確</p>
</div>

以上幾行很友好的實現(xiàn)從必填項、格式進行校驗,而這一切都是依靠 [(ngModel)] 統(tǒng)一采集,得以只需要利用一個模板引用變量訪問到每個校驗指令的錯誤信息。

1、[(ngModel)] 到底做了什么?

在解析這個問題前需要先了解一下 RequiredValidator 是如何定義的。

@Directive({
 providers: [{
   provide: NG_VALIDATORS,
   useExisting: forwardRef(() => RequiredValidator),
   multi: true
  }]
})
export class RequiredValidator {}

只看最核心向 NG_VALIDATORS 標識符注冊一個 RequiredValidator 指令。這樣就可以使 ngModel 指令中注入 NG_VALIDATORS 后就能得到這個指令對象。

ngModel 我把它簡化了一下:

export class NgModel extends NgControl {
  constructor(@Inject(NG_VALIDATORS) validators: Array<Validator|ValidatorFn>) {}
  
  get validator(): ValidatorFn|null {
    // 各種校驗并返回結(jié)果
  }
}

有關(guān)更多ng_model.ts可以深入閱讀源代碼。

Angular會在每一次表單值變更時,對所有的表單中已經(jīng)安裝的校驗器進行一次遍歷。

二、編寫一個校驗器

誠如 required 校驗器一樣,依然是把自定義校驗器掛到 NG_VALIDATORS 當中。假如我們希望手機文本框只能輸入 159 開頭的一個校驗器。

定義Directive

@Directive({
  selector: '[user-mobile]',
  exportAs: 'userMobile',
  providers: [{
    provide: NG_VALIDATORS,
    useExisting: forwardRef(() => UserMobileDirective),
    multi: true
  }]
})
export class UserMobileDirective {}

一個非常普通的指令定義方法,只是多了一個將 UserMobileDirective 注冊到 NG_VALIDATORS 標識符當中而已。別問我為什么,一種約定。

export class UserMobileDirective implements Validator {
  validate(c: AbstractControl): { [key: string]: any; } {
    let value: string = c.value || '';
    if (!value.startsWith('159')) {
      return {
        mobile: {
          msg: '手機號必須是159開頭',
          actualValue: value
        }
      };
    }
    return null;
  }
}

只需要實現(xiàn) Validator 接口的 validate 方法即可。

從 c 中獲取DOM值,當遇到非 159 開頭時,返回一個用于表述消息的對象即可,否則返回一個 null。這個對象會被統(tǒng)一采集在 ngModel.errors 對象下面。故而,只需要在DOM元素加上 user-mobile 指令即可。

<input user-mobile [(ngModel)]="user.mobile" #mobile="ngModel" autocomplete="off" type="tel" class="form-control" name="mobile" id="mobile" required maxlength="11">
<div *ngIf="mobile.errors">
  <p *ngIf="mobile.errors.required">手機號必填</p>
  <p *ngIf="mobile.errors.mobile">{{mobile.errors.mobile.msg}}</p>
</div>

接口還包括一個 registerOnValidatorChange 可選方法,當某些其它外部屬性的變更時,允許重新手動觸發(fā)校驗。

三、異步校驗器

如果說用戶手機校驗器需要檢查手機是否為黑名單的情況下,正常黑名單數(shù)據(jù)都存在遠程當中。這樣情況下需要發(fā)送HTTP請求,而這一過程就是異步。

Angular針對這類異步校驗有獨立的另一個標識符,即:NG_ASYNC_VALIDATORS,而其它代碼都是相通的。

@Directive({
  selector: '[user-async]',
  exportAs: 'userAsync',
  providers: [{
    provide: NG_ASYNC_VALIDATORS,
    useExisting: forwardRef(() => UserAsyncDirective),
    multi: true
  }]
})
export class UserAsyncDirective implements Validator {
  validate(c: AbstractControl): Observable<any> {
    return c.valueChanges
        // 去抖
        .debounceTime(300)
        // 抑制重復值
        .distinctUntilChanged()
        // 1、可以使用flatMap進行遠程校驗
        // .flatMap(value => value)
        // 2、本地模擬判斷
        .map((value: string) => {
          if ([ '15900000001', '15900000002' ].includes(value)) {
            return {
              mobile: {
                msg: '手機號為黑名',
                actualValue: value
              }
            }
          }
          return null;
        })
        .first();    
  }
}

除了 NG_ASYNC_VALIDATORS 核心的結(jié)構(gòu)完全沒有變動。

而對于 validate 方法返回的是一個 Observable 類型,利用對 valueChanges 的訂閱可以制作一些像去抖動作。

而最后必須使用 first() 做為結(jié)尾,原因每一次校驗,對于結(jié)果而言只允許一個。

結(jié)論

本章介紹的是如何對模板驅(qū)動表單創(chuàng)建自定義校驗器,它相比較響應式表單自定義校驗器略為復雜一些。但是實際運用中,我們不應該只為某個構(gòu)建表單風格做一種自定義校驗器,應該二者是共存的。

比如上面 159 開頭的示例。更合理的編寫方式應該是將校驗邏輯獨立:

export class MyValidators {
  static checkMobile(value: string): ValidationErrors|null {
    return !value.startsWith('159') ? { mobile: { msg: '手機號必須是159開頭' } } : null;
  }
}
// 校驗器類
export class UserMobileDirective implements Validator {
  validate(c: AbstractControl): { [key: string]: any; } {
    let value: string = c.value || '';
    return MyValidators.checkMobile(value);
  }
}

這樣,同一個校驗器,不管是模板驅(qū)動表單還是響應式表單,都能是通用的。

總結(jié)

以上所述是小編給大家介紹的Angular在模板驅(qū)動表單中自定義校驗器的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • AngularJS基礎(chǔ)教程之簡單介紹

    AngularJS基礎(chǔ)教程之簡單介紹

    本教程旨在幫助你盡可能快速而有效地學習AngularJS。通過該教程你會學習到AngularJS的一些基本特性,例如指令、表達式、過濾器、模塊和控制器等。以及其它所有你需要知道的有關(guān)AngularJS的東西,如事件、DOM節(jié)點、表單、用戶輸入、數(shù)據(jù)驗證、Http對象等。
    2015-09-09
  • 深入解析AngularJS框架中$scope的作用與生命周期

    深入解析AngularJS框架中$scope的作用與生命周期

    這篇文章主要介紹了AngularJS中$scope的作用與生命周期,包括在DOM中添加controller對象的相關(guān)用法,需要的朋友可以參考下
    2016-03-03
  • 淺談angularjs $http提交數(shù)據(jù)探索

    淺談angularjs $http提交數(shù)據(jù)探索

    這篇文章主要介紹了淺談angularjs $http提交數(shù)據(jù)探索,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-01-01
  • AngularJS通過ng-route實現(xiàn)基本的路由功能實例詳解

    AngularJS通過ng-route實現(xiàn)基本的路由功能實例詳解

    這篇文章主要介紹了AngularJS通過ng-route實現(xiàn)基本的路由功能,結(jié)合實例形式詳細分析了AngularJS使用ng-route實現(xiàn)路由功能的操作步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2016-12-12
  • AngularJS 中括號的作用詳解

    AngularJS 中括號的作用詳解

    這篇文章主要介紹了AngularJS 中括號的作用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • AngularJs 終極購物車(實例講解)

    AngularJs 終極購物車(實例講解)

    下面小編就為大家?guī)硪黄狝ngularJs 終極購物車的實例講解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • angularjs 指令實現(xiàn)自定義滾動條效果

    angularjs 指令實現(xiàn)自定義滾動條效果

    橫向商品欄,把原有的滾動條改成自定義的樣式,并且給兩邊加上箭頭可以調(diào)整,可以拖動商品和滾輪實現(xiàn)滾動條效果,這篇文章主要介紹了angularjs 指令實現(xiàn)自定義滾動條效果,需要的朋友可以參考下
    2024-03-03
  • angular+ionic 的app上拉加載更新數(shù)據(jù)實現(xiàn)方法

    angular+ionic 的app上拉加載更新數(shù)據(jù)實現(xiàn)方法

    這篇文章主要介紹了angular+ionic 的app上拉加載更新數(shù)據(jù)實現(xiàn)方法,需要的的朋友參考下
    2017-01-01
  • Angular獲取手機驗證碼實現(xiàn)移動端登錄注冊功能

    Angular獲取手機驗證碼實現(xiàn)移動端登錄注冊功能

    最近在使用angular來做項目,功能要求實現(xiàn)一是點擊按鈕獲取驗證碼,二是點擊登錄驗證表單。之前用jquery來做項目很好做,使用angular怎么實現(xiàn)呢?其實實現(xiàn)代碼也很簡單的,下面通過實例代碼給大家介紹下,需要的朋友參考下吧
    2017-05-05
  • Angular利用trackBy提升性能的方法

    Angular利用trackBy提升性能的方法

    這篇文章主要介紹了在Angular中利用trackBy來提升性能的實現(xiàn)方法,需要的朋友可以參考下
    2018-01-01

最新評論