angular自定义验证器添加入模板驱动表单
-
创建自定义验证器的命令
ng generate directive forbidden-name(自定义床啊金验证器的名称)
-
生成的文件内容
import { Directive } from '@angular/core';
@Directive({
selector: '[appForbiddenName]'
})
export class ForbiddenNameDirective {
constructor() { }
}
-
创建一个文件用来放置正则判断的验证器算法。validatot.ts
import { ValidatorFn, AbstractControl } from '@angular/forms';
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
// 返回一个具有验证性函数
return (control: AbstractControl): { [key: string]: any } | null => {
console.log("control.value=",control.value)
// control.value控件的值
const forbidden = nameRe.test(control.value);
console.log("forbidden=",forbidden)
// 下面是三目运算符,当forbidden为false的时候,返回null,当forbidden为true的时候,返回{'forbiddenNAme':{value:control.value}}
return forbidden ? { 'forbiddenName': { value: control.value } } : null;
};
}
-
在刚刚生成的自定义验证器中继承并实现一个接口
import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl} from '@angular/forms';
import { forbiddenNameValidator } from './validator';
@Directive({
selector: '[appForbiddenName]', // 指令作为属性使用
providers:[{provide:NG_VALIDATORS,useExisting:ForbiddenNameDirective,multi:true}]
})
export class ForbiddenNameDirective implements Validator {
@Input('appForbiddenName') forbiddenName: string; // 获取指令值
// 指令实现接口,也就是说,在调用这条指令的时候,就已经能够启动这个函数
validate(control: AbstractControl): {[key: string]: any} | null {
// 键值对:map[key:string]any {[key: string]: any} | null接收返回值的类型有键值对或者是NULL
console.log("control:",control)
console.log("forbiddenName=",this.forbiddenName)
// 还是三目运算符,this.forbidden为空的时候,不进行匹配
return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control): null;
}
constructor() { }
}
有一个关键的地方是,实现Validator接口之后,要能够给全局的模板都能够实现,要注册。注册的密钥是angular固定提供的一种NG_VALIDATORS。注册的具体语句:
providers:[{provide:NG_VALIDATORS,useExisting:ForbiddenNameDirective,multi:true}]
-
使用模板自定义的方法
<div>
<label for="name">姓名:</label>
<input id="name" class="form-control" ngModel name="name" #name='ngModel' appForbiddenName="bob" required
minlength="3" style="width: 200px;height: 30px;">
</div>
<!-- forbiddenName="bob" 自定义的 -->
<div *ngIf="name.invalid &&(name.dirty||name.touched)">
<div *ngIf="name.errors.required">
Name is required
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 3 characters long.
</div>
<!-- appForbiddenName="bob"说明这个控件绑定了一个验证器,{ 'forbiddenName': { value: control.value } } 这个是返回值,有值则出现,无值就不出现 -->
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>