<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

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

        來源:懂視網 責編:小采 時間:2020-11-27 22:33:06
        文檔

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

        Angular在模板驅動表單中自定義校驗器的方法:引言 模板驅動表單相比較響應式表單可以少更少的代碼做同樣的事情,可也損失了自由度與更易測試,當然很多人并不在乎啦。 所以我相信很多人在編寫Angular不自由自主去更傾向于模板驅動表單的寫法。 表單最核心的是校驗體驗,在Angular中簡直就是發揮到了極致
        推薦度:
        導讀Angular在模板驅動表單中自定義校驗器的方法:引言 模板驅動表單相比較響應式表單可以少更少的代碼做同樣的事情,可也損失了自由度與更易測試,當然很多人并不在乎啦。 所以我相信很多人在編寫Angular不自由自主去更傾向于模板驅動表單的寫法。 表單最核心的是校驗體驗,在Angular中簡直就是發揮到了極致

        引言

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

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

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

        然后很多時候我們需要一些特殊的校驗,比如:數據比較、遠程校驗等。那在模板驅動表單風格中我們要如何優雅的實現這樣一個校驗器呢?

        一、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>

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

        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 {
         // 各種校驗并返回結果
         }
        }

        有關更多ng_model.ts可以深入閱讀源代碼。

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

        二、編寫一個校驗器

        誠如 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;
         }
        }

        只需要實現 Validator 接口的 validate 方法即可。

        從 c 中獲取DOM值,當遇到非 159 開頭時,返回一個用于表述消息的對象即可,否則返回一個 null。這個對象會被統一采集在 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 可選方法,當某些其它外部屬性的變更時,允許重新手動觸發校驗。

        三、異步校驗器

        如果說用戶手機校驗器需要檢查手機是否為黑名單的情況下,正常黑名單數據都存在遠程當中。這樣情況下需要發送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 核心的結構完全沒有變動。

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

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

        結論

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

        比如上面 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);
         }
        }

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

        總結

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

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

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

        Angular在模板驅動表單中自定義校驗器的方法:引言 模板驅動表單相比較響應式表單可以少更少的代碼做同樣的事情,可也損失了自由度與更易測試,當然很多人并不在乎啦。 所以我相信很多人在編寫Angular不自由自主去更傾向于模板驅動表單的寫法。 表單最核心的是校驗體驗,在Angular中簡直就是發揮到了極致
        推薦度:
        標簽: 驗證 an 驗證器
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 国产无遮挡无码视频免费软件| 免费视频淫片aa毛片| 国产精品美女久久久免费| 91av免费在线视频| 拍拍拍无挡视频免费观看1000| 老司机精品免费视频| 成人影片一区免费观看| 日本v片免费一区二区三区| 久青草国产免费观看| 国产伦精品一区二区免费| 国产免费拔擦拔擦8X高清在线人| 免费h视频在线观看| h片在线免费观看| 91免费国产自产地址入| 成人av免费电影| 你懂得的在线观看免费视频| 97国产在线公开免费观看| 黄瓜视频影院在线观看免费| 狼友av永久网站免费观看| 亚洲天堂中文字幕在线| 香蕉视频在线观看亚洲| 中文字幕精品三区无码亚洲| 成人福利在线观看免费视频| 亚洲爆乳无码精品AAA片蜜桃| 国产亚洲精品免费| 日本免费人成网ww555在线| 国产香蕉九九久久精品免费| 亚洲免费在线视频观看| 国产精品深夜福利免费观看| 亚洲高清国产AV拍精品青青草原| 亚洲人成毛片线播放| 一个人看的hd免费视频| 成年网站免费视频A在线双飞| 亚洲人午夜射精精品日韩| 亚洲伊人久久大香线焦| 国产精品无码永久免费888| 青娱乐免费视频在线观看| 亚洲综合伊人久久综合| 亚洲av成人一区二区三区观看在线| 国产精品免费AV片在线观看| 国产精品酒店视频免费看|