最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Angular在模板驅(qū)動(dòng)表單中自定義校驗(yàn)器的方法

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

引言

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

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

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

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

一、Angular是如何校驗(yàn)?

一般在編寫(xiě)一個(gè)手機(jī)文本框可能是這樣:

<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">手機(jī)號(hào)必填</p>
  <p *ngIf="mobile.errors.pattern">手機(jī)號(hào)格式不正確</p>
</div>

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

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

在解析這個(gè)問(wèn)題前需要先了解一下 RequiredValidator 是如何定義的。

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

只看最核心向 NG_VALIDATORS 標(biāo)識(shí)符注冊(cè)一個(gè) RequiredValidator 指令。這樣就可以使 ngModel 指令中注入 NG_VALIDATORS 后就能得到這個(gè)指令對(duì)象。

ngModel 我把它簡(jiǎn)化了一下:

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

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

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

二、編寫(xiě)一個(gè)校驗(yàn)器

誠(chéng)如 required 校驗(yàn)器一樣,依然是把自定義校驗(yàn)器掛到 NG_VALIDATORS 當(dāng)中。假如我們希望手機(jī)文本框只能輸入 159 開(kāi)頭的一個(gè)校驗(yàn)器。

定義Directive

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

一個(gè)非常普通的指令定義方法,只是多了一個(gè)將 UserMobileDirective 注冊(cè)到 NG_VALIDATORS 標(biāo)識(shí)符當(dāng)中而已。別問(wèn)我為什么,一種約定。

類(lèi)

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

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

從 c 中獲取DOM值,當(dāng)遇到非 159 開(kāi)頭時(shí),返回一個(gè)用于表述消息的對(duì)象即可,否則返回一個(gè) null。這個(gè)對(duì)象會(huì)被統(tǒng)一采集在 ngModel.errors 對(duì)象下面。故而,只需要在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">手機(jī)號(hào)必填</p>
  <p *ngIf="mobile.errors.mobile">{{mobile.errors.mobile.msg}}</p>
</div>

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

三、異步校驗(yàn)器

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

Angular針對(duì)這類(lèi)異步校驗(yàn)有獨(dú)立的另一個(gè)標(biāo)識(shí)符,即: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)
        // 抑制重復(fù)值
        .distinctUntilChanged()
        // 1、可以使用flatMap進(jìn)行遠(yuǎn)程校驗(yàn)
        // .flatMap(value => value)
        // 2、本地模擬判斷
        .map((value: string) => {
          if ([ '15900000001', '15900000002' ].includes(value)) {
            return {
              mobile: {
                msg: '手機(jī)號(hào)為黑名',
                actualValue: value
              }
            }
          }
          return null;
        })
        .first();    
  }
}

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

而對(duì)于 validate 方法返回的是一個(gè) Observable 類(lèi)型,利用對(duì) valueChanges 的訂閱可以制作一些像去抖動(dòng)作。

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

結(jié)論

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

比如上面 159 開(kāi)頭的示例。更合理的編寫(xiě)方式應(yīng)該是將校驗(yàn)邏輯獨(dú)立:

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

這樣,同一個(gè)校驗(yàn)器,不管是模板驅(qū)動(dòng)表單還是響應(yīng)式表單,都能是通用的。

總結(jié)

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

相關(guān)文章

  • AngularJS使用ui-route實(shí)現(xiàn)多層嵌套路由的示例

    AngularJS使用ui-route實(shí)現(xiàn)多層嵌套路由的示例

    這篇文章主要介紹了AngularJS使用ui-route實(shí)現(xiàn)多層嵌套路由的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • Angular 如何使用第三方庫(kù)的方法

    Angular 如何使用第三方庫(kù)的方法

    本篇文章主要介紹了Angular 如何使用第三方庫(kù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • Angular跨字段驗(yàn)證器中如何直接調(diào)用其它獨(dú)立的驗(yàn)證器

    Angular跨字段驗(yàn)證器中如何直接調(diào)用其它獨(dú)立的驗(yàn)證器

    我們?cè)陂_(kāi)發(fā)的時(shí)候都會(huì)用到表單,那么驗(yàn)證器就是必不可少的東西,這篇文章主要給大家介紹了關(guān)于在Angular跨字段驗(yàn)證器中如何直接調(diào)用其它獨(dú)立的驗(yàn)證器的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • AngularJS中$http的交互問(wèn)題

    AngularJS中$http的交互問(wèn)題

    本篇文章主要介紹了AngularJS中$http的交互問(wèn)題 ,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • angular route中使用resolve在uglify壓縮后問(wèn)題解決

    angular route中使用resolve在uglify壓縮后問(wèn)題解決

    這篇文章主要介紹了angular route中使用resolve在uglify壓縮后問(wèn)題解決的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 詳解Angular2響應(yīng)式表單

    詳解Angular2響應(yīng)式表單

    這篇文章主要介紹了詳解Angular2響應(yīng)式表單,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • 使用Angular.js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車(chē)功能

    使用Angular.js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車(chē)功能

    在各大購(gòu)物網(wǎng)站大家都可以簡(jiǎn)單購(gòu)物車(chē)效果演示,下面通過(guò)本文給大家分享一段代碼關(guān)于使用Angular.js實(shí)現(xiàn)簡(jiǎn)單的購(gòu)物車(chē)功能,需要的朋友可以參考下
    2016-11-11
  • AngularJS刪除路由中的#符號(hào)的方法

    AngularJS刪除路由中的#符號(hào)的方法

    這篇文章主要介紹了AngularJS刪除路由中的#符號(hào)的方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • 全面解析Angular中$Apply()及$Digest()的區(qū)別

    全面解析Angular中$Apply()及$Digest()的區(qū)別

    $apply()和$digest()在AngularJS中是兩個(gè)核心概念,但是有時(shí)候它們又讓人困惑。這篇文章主要介紹了Angular中$Apply()及$Digest()區(qū)別詳細(xì)說(shuō)明的相關(guān)資料,需要的朋友可以參考下
    2016-08-08
  • angular學(xué)習(xí)之ngRoute路由機(jī)制

    angular學(xué)習(xí)之ngRoute路由機(jī)制

    這篇文章主要介紹了angular學(xué)習(xí)之ngRoute路由機(jī)制,ngRoute是一個(gè)Module,提供路由和深層鏈接所需的服務(wù)和指令。有需要的可以了解一下。
    2017-04-04

最新評(píng)論

合水县| 靖宇县| 泉州市| 阳朔县| 抚远县| 盖州市| 霍邱县| 青冈县| 武清区| 瓦房店市| 长顺县| 宁城县| 司法| 旬阳县| 富川| 合川市| 临湘市| 永嘉县| 余姚市| 黄平县| 樟树市| 威信县| 灵宝市| 图木舒克市| 广宗县| 贵定县| 泊头市| 广东省| 琼中| 乌兰察布市| 丰县| 南漳县| 个旧市| 静宁县| 兴城市| 丽水市| 宝应县| 滨海县| 濉溪县| 横峰县| 深圳市|