我們會(huì)在本文中探索 Angular 2 內(nèi)建的自定義驗(yàn)證。
網(wǎng)站建設(shè)、網(wǎng)站制作的開發(fā),更需要了解用戶,從用戶角度來建設(shè)網(wǎng)站,獲得較好的用戶體驗(yàn)。創(chuàng)新互聯(lián)建站多年互聯(lián)網(wǎng)經(jīng)驗(yàn),見的多,溝通容易、能幫助客戶提出的運(yùn)營建議。作為成都一家網(wǎng)絡(luò)公司,打造的就是網(wǎng)站建設(shè)產(chǎn)品直銷的概念。選擇創(chuàng)新互聯(lián)建站,不只是建站,我們把建站作為產(chǎn)品,不斷的更新、完善,讓每位來訪用戶感受到浩方產(chǎn)品的價(jià)值服務(wù)。
# 介紹
Angular 2 原生就支持一些有用的驗(yàn)證器:
我們會(huì)基于下面的接口創(chuàng)建一個(gè)表單來獲取用戶信息。
// user.interface.ts
export interface User {
username: string; // required, must be 5-8 characters
email: string; // required, must be valid email format
password: string; // required, value must be equal to confirm password.
confirmPassword: string; // required, value must be equal to password.
}需求
僅在字段數(shù)據(jù)不正確或提交表單的時(shí)候,為每個(gè)字段 顯示錯(cuò)誤消息 。
UI 展示:
# App 配置
這是我們的文件結(jié)構(gòu):
|- app/ |- app.component.html |- app.component.ts |- app.module.ts |- equal-validator.directive.ts |- main.ts |- user.interface.ts |- index.html |- styles.css |- tsconfig.json
為了使用新的表單模塊,我們需要用 npm install @ angular/forms 指令調(diào)用 npm 包,并在應(yīng)用程序模塊中導(dǎo)入最新的表單模塊。
$ npm install @angular/forms --save
下面是我們應(yīng)用程序的 app.module.ts 模塊:
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ], // import forms module here
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
})
export class AppModule { }# App 組件
讓我們繼續(xù)創(chuàng)建 App 組件。
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { User } from './user.interface';
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent implements OnInit {
public user: User;
ngOnInit() {
// initialize model here
this.user = {
username: '',
email: '',
password: '',
confirmPassword: ''
}
}
save(model: User, isValid: boolean) {
// 調(diào)用API保存customer
console.log(model, isValid);
}
}# HTML 視圖
這是我們的 HTML 視圖的樣子。
<!-- app.component.html --> <div> <h2>Add user</h2> <form #f="ngForm" novalidate (ngSubmit)="save(f.value, f.valid)"> <!-- 我們將把驗(yàn)證的字段放在這里 --> <button type="submit" [disabled]="!myForm.valid">Submit</button> </form> </div>
現(xiàn)在來一個(gè)個(gè)添加控件。
用戶名
需求: 必填,長度在 5-8 個(gè)字符之間
<!-- app.component.html -->
...
<div>
<label>Username</label>
<input type="text" name="username" [ngModel]="user.username"
required minlength="5" maxlength="8" #username="ngModel">
<small [hidden]="username.valid || (username.pristine && !f.submitted)">
Username is required (minimum 5 characters).
</small>
</div>
<pre *ngIf="username.errors">{{ username.errors | json }}</pre>
...required、minlength、maxlength 都是內(nèi)置的驗(yàn)證器,所以很容易使用。
我們只會(huì)在用戶名無效、獲得焦點(diǎn)和提交表單的情況下顯示錯(cuò)誤消息。最后一條的 pre 標(biāo)簽在開發(fā)過程中對(duì)調(diào)試很有用。它會(huì)顯示字段的所有驗(yàn)證錯(cuò)誤。
電子郵件地址
需求: 必填,必須是有效的電子郵件地址格式
<!-- app.component.html --> ... <div> <label>Email</label> <input type="email" name="email" [ngModel]="user.email" required pattern="^[a-zA-Z0–9_.+-]+@[a-zA-Z0–9-]+.[a-zA-Z0–9-.]+$" #email="ngModel" > <small [hidden]="email.valid || (email.pristine && !f.submitted)"> Email is required and format should be <i>john@doe.com</i>. </small> </div> ...
我們把 email 設(shè)置為必填,然后使用內(nèi)建的模板驗(yàn)證器,通過正則表達(dá)式來檢查 email 的值:^[a-zA-Z0–9_.+-]+@[a-zA-Z0–9-]+.[a-zA-Z0–9-.]+$.
密碼和確認(rèn)密碼
需求:
<!-- app.component.html --> ... <div> <label>Password</label> <input type="password" name="password" [ngModel]="user.password" required #password="ngModel"> <small [hidden]="password.valid || (password.pristine && !f.submitted)"> Password is required </small> </div> <div> <label>Retype password</label> <input type="password" name="confirmPassword" [ngModel]="user.confirmPassword" required validateEqual="password" #confirmPassword="ngModel"> <small [hidden]="confirmPassword.valid || (confirmPassword.pristine && !f.submitted)"> Password mismatch </small> </div> ...
validateEqual 是我們自定義的驗(yàn)證器。它會(huì)將當(dāng)前輸入的值與輸入的密碼值進(jìn)行對(duì)比驗(yàn)證。
# 自定義確認(rèn)密碼驗(yàn)證器
我們將制定一個(gè) validate equal 指令。
// equal-validator.directive.ts
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
constructor( @Attribute('validateEqual') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {
// self value (e.g. retype password)
let v = c.value;
// control value (e.g. password)
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}
}代碼很長,讓我們把它拆開一部分一部分地看。
申明指令
// equal-validator.directive.ts
@Directive({
selector: '[validateEqual][formControlName],[validateEqual]
[formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})首先,我們使用 @Directive 注解定義指令。然后我們指定 selector。selector 是必須的。我們會(huì)擴(kuò)展內(nèi)建驗(yàn)證器集合 NG_VALIDATORS 來將我們的等值驗(yàn)證器用于 providers.
// equal-validator.directive.ts
export class EqualValidator implements Validator {
constructor( @Attribute('validateEqual') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {}
}我們的指令類必須實(shí)現(xiàn) Validator 接口。Validator 接口需要 avalidate 函數(shù)。在構(gòu)建函數(shù)中,我們通過 @Attribute('validateEqual') 注解注入屬性值,并將其賦值給 validateEqual 變量。在我們的示例中, validateEqual 的值是 "password" 。
實(shí)現(xiàn)驗(yàn)證
// equal-validator.directive.ts
validate(c: AbstractControl): { [key: string]: any } {
// 自己的值 (如 retype password)
let v = c.value;
// 控件的值 (如 password)
let e = c.root.get(this.validateEqual);
// 值不等旱
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}首先我們從輸入控件讀入值,賦給 v。然后我們?cè)诒韱沃姓业?password 控件的值賦值給 e。之后檢查值是否相等,如果不等就返回錯(cuò)。
# 在應(yīng)用模塊中導(dǎo)入自定義驗(yàn)證器
要使用自定義驗(yàn)證器,需要先將其導(dǎo)入到應(yīng)用程序模塊中。
// app.module.ts
...
import { EqualValidator } from './equal-validator.directive'; // 導(dǎo)入驗(yàn)證器
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, EqualValidator ], // 導(dǎo)入到應(yīng)用模塊
bootstrap: [ AppComponent ],
})
...好了!假如你在 password 字段中輸入 "123",在 retype password 字段中輸入"xyz",就會(huì)顯示一個(gè)密碼不匹配的錯(cuò)誤。
# 看起來挺好,但是……
現(xiàn)在一切都挺好,直到你 在 retype passowrd 中輸入文本之后 又修改了 password 字段的值。
比如,你在 password 字段中輸入 "123",在 retype password 字段中也輸入 "123", 然后將 password 字段的值改為 "1234" 。驗(yàn)證仍然通過。 為什么?
因?yàn)槲覀冎话训戎凋?yàn)證器應(yīng)用到 retype password 字段。只有當(dāng) retype password 的值發(fā)生變化時(shí)才會(huì)觸發(fā)驗(yàn)證。
解決辦法
有幾種方法可以解決這個(gè)問題。我們這里只討論其中一種,你自己可以去找到其它辦法。我們會(huì)再次使用 validateEqual 驗(yàn)證器并 添加 一個(gè) reverse 屬性。
<!-- app.component.html --> ... <input type="password" class="form-control" name="password" [ngModel]="user.password" required validateEqual="confirmPassword" reverse="true"> <input type="password" class="form-control" name="confirmPassword" [ngModel]="user.confirmPassword" required validateEqual="password"> ...
在我們的例子中,我們?cè)O(shè)置 password 驗(yàn)證的 reverse 為 true。只要 password 與 retype password 的 值不等,我們會(huì)為確證密碼字段添加一個(gè)錯(cuò)誤消息,而不是重置 password 字段。
完整的自定義驗(yàn)證器代碼如下:
// equal-validator.directive.ts
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
constructor(@Attribute('validateEqual') public validateEqual: string,
@Attribute('reverse') public reverse: string) {
}
private get isReverse() {
if (!this.reverse) return false;
return this.reverse === 'true' ? true: false;
}
validate(c: AbstractControl): { [key: string]: any } {
// self value
let v = c.value;
// control vlaue
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value && !this.isReverse) {
return {
validateEqual: false
}
}
// value equal and reverse
if (e && v === e.value && this.isReverse) {
delete e.errors['validateEqual'];
if (!Object.keys(e.errors).length) e.setErrors(null);
}
// value not equal and reverse
if (e && v !== e.value && this.isReverse) {
e.setErrors({ validateEqual: false });
}
return null;
}
}當(dāng)然,還有其他方法也能解決密碼和確認(rèn)密碼驗(yàn)證問題。有些人建議在組( stack overflow )中添加密碼和確認(rèn)密碼的機(jī)制,然后驗(yàn)證它。
方法沒有絕對(duì)的好與壞,適合自己的才是最好的。
以上所述是小編給大家介紹的在 Angular2 中實(shí)現(xiàn)自定義校驗(yàn)指令(確認(rèn)密碼)的方法,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!
分享題目:在Angular2中實(shí)現(xiàn)自定義校驗(yàn)指令(確認(rèn)密碼)的方法
URL地址:http://www.chinadenli.net/article32/pecepc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、App開發(fā)、面包屑導(dǎo)航、品牌網(wǎng)站設(shè)計(jì)、、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)