引言
模板驅(qū)動(dòng)表單相比較響應(yīng)式表單可以少更少的代碼做同樣的事情,可也損失了自由度與更易測(cè)試,當(dāng)然很多人并不在乎啦。
所以我相信很多人在編寫Angular不自由自主去更傾向于模板驅(qū)動(dòng)表單的寫法。
表單最核心的是校驗(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)?
一般在編寫一個(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è)模板引用變量訪問到每個(gè)校驗(yàn)指令的錯(cuò)誤信息。
1、[(ngModel)] 到底做了什么?
在解析這個(gè)問題前需要先了解一下 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)行一次遍歷。
二、編寫一個(gè)校驗(yàn)器
誠(chéng)如 required 校驗(yàn)器一樣,依然是把自定義校驗(yàn)器掛到 NG_VALIDATORS 當(dāng)中。假如我們希望手機(jī)文本框只能輸入 159 開頭的一個(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)中而已。別問我為什么,一種約定。
新聞熱點(diǎn)
疑難解答
圖片精選