Angular2表单自定义验证器的实现


Posted in Javascript onOctober 19, 2016

本文主要给大家介绍如何判断验证器的结果。在这里,我们就来看看怎样实现一个自定义的验证器。

目标

我们要实现一个验证手机号的验证器,使用的实例还是基于之前的文章里面的实例,也就是用户信息输入的表单页面。我们在手机号的元素上添加一个验证手机号的验证器。然后,如果手机号验证失败,就显示一个错误,页面如下:

Angular2表单自定义验证器的实现

这部分教程的代码可以从github获取:

git clone

https://github.com/Mavlarn/angular2-forms-tutorial

如果要运行,进入项目目录,运行下面的命令安装依赖然后运行测试服务器:

cd angular2-forms-tutorial
git checkout model-driven # 检出该文所使用的tag
npm install
npm start

实现验证器

在Angular2中,实现一个验证器非常简单,就是一个方法就可以,该方法的参数是一个FormControl,结果是一个错误对象或者null。用TypeScript接口表示,就是这样:

interface Validator<T extends FormControl> {
(c:T): {[error: string]:any};
}

如果是对类似Java这样的面向对象语言比较了解的话,上面的接口定义就很容易理解。其中<T extends FormControl>是指这个方法中用到一个泛型T,它是一个继承自FormControl的对象。(c:T): {[error: string]:any};这是一个lambda表达式的方法定义,参数c的类型为T,这个方法返回一个对象。

我们创建一个名为mobile.validator.ts的文件,它的内容如下:

import { FormControl } from '@angular/forms';
export function validateMobile(c: FormControl) {
let MOBILE_REGEXP = /^1[0-9]{10,10}$/;
return MOBILE_REGEXP.test(c.value) ? null : {
validateMobile: {valid: false}
}
}

在这个验证方法里,参数c的类型为FormControl,也就是表单控件,他有一个value属性,存放当前的值。我们使用正则表达式,来判断这个值是否合法。如果不合法,就返回一个对象。
在之前的教程中,我们对验证器的验证结果是这样获得的:

<p *ngIf="userForm.controls.mobile?.errors?.required">必须输入电话</p>

userForm.controls.mobile就是表单中手机号这个控件,required是required验证器对应的key,当required验证器验证失败时,就会在errors里面添加一个值:

{
required: {valid: false}
}

所以,我们实现的自定义的验证器,也要把验证结果用验证器的名字作为key,放到errors里面,就是这样:

{
validateMobile: {valid: false}
}

这样,我们就能够在页面中用跟之前同样的方式来获得这个验证器的验证结果。

在模型驱动的表单里添加验证器

接下来,我们把我们实现的验证器添加到我们的表单里,先加到模型驱动的表单里:

import { validateMobile } from '../validators/mobile.validator';
export class ReactiveFormsComponent implements OnInit {
this.userForm = this.formBuilder.group({
// ... 省略其他控件
mobile: [13800138001, [Validators.required, Validators.minLength(11), Validators.maxLength(11), validateMobile]]
});
...
}

上面的代码省略了其他的部分,完整的代码,请参考github。

在上面的代码中,我们引入了之前实现的自定义的验证器,然后在表单控件创建代码中,对mobile控件加了一个validateMobile。

这样,我们在页面上添加相应的验证结果信息:

<p *ngIf="userForm.controls.mobile.errors?.validateMobile">电话号码格式不正确</p>

这样就完成了验证器,以及在页面显示验证结果,就这么简单。

在模板驱动的表单里添加验证器

但是,如果我们的表单不是在组件里用模型驱动的方式创建的,而是在页面上用html元素创建的,那么使用自定义的验证器就稍微麻烦一点。

在一个模板驱动的表单里,我们是这样使用验证器的:

<input type="text" name="mobile" [(ngModel)]="user.mobile" #mobile="ngModel" required minlength="11" maxlength="11">
<span *ngIf="mobile.valid">有效</span>
<div [hidden]="mobile.valid || mobile.pristine">
<p *ngIf="mobile.errors?.minlength || mobile.errors?.maxlength">电话长度必须为11</p>
<p *ngIf="mobile.errors?.required">必须输入姓名</p>
</div>

也就是在input输入元素的属性中添加验证器。那么,我们要实现自己的验证器在表单里面使用,除了上面的验证器方法里面,还需要2件事情:

我们需要将这个验证器定义成一个指令Directive,这样Angular在解析这段html的时候,会识别我们自定义的验证器指令。
我们还需要Angular的验证器调用我们的验证方法。
所以,在之前的mobile.validator.ts文件里,添加下面的指令定义:

@Directive({
selector: '[validateMobile][ngModel]'
})
export class MobileValidator {}

这段代码很简单,就是用@Directive标签定义了一个指令MobileValidator,它作用的元素是同时具有validateMobile和ngModel属性的元素。这样,我们就可以在手机号的元素上添加一个属性,来使这个验证器指令起作用。
然后,我们还需要Angular的验证器框架能够调用我们的验证方法,这就需要NG_VALIDATORS。我们修改上面的验证器的指令定义如下:

@Directive({
selector: '[validateMobile][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useValue: validateMobile, multi: true }
]
})
export class MobileValidator {}

这样Angular的验证器就能够将validateMobile方法应用在这个指令上。

最后,我们再把这个新的指令,添加到AppModule的declarations里面,就可以在页面上使用这个验证器了。

最后,页面上使用验证器的代码如下:

<input type="text" name="mobile" [(ngModel)]="user.mobile" #mobile="ngModel" required minlength="11" maxlength="11" validateMobile>
<span *ngIf="mobile.valid">有效</span>
<div [hidden]="mobile.valid || mobile.pristine">
<p *ngIf="mobile.errors?.minlength || mobile.errors?.maxlength">电话长度必须为11</p>
<p *ngIf="mobile.errors?.required">必须输入姓名</p>
<p *ngIf="mobile.errors?.validateMobile">电话号码格式不正确</p>
</div>

以上所述是小编给大家介绍的Angular2表单自定义验证器,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery-ui中自动完成实现方法
Jun 10 Javascript
js如何获取file控件的完整路径具体实现代码
May 15 Javascript
javascript动态创建及删除元素的方法
Dec 22 Javascript
javascript实现滚动效果的数字时钟实例
Jul 21 Javascript
Angular 4环境准备与Angular cli创建项目详解
May 27 Javascript
详解用vue.js和laravel实现微信支付
Jun 23 Javascript
详解在React里使用&quot;Vuex&quot;
Apr 02 Javascript
详解如何在vue项目中使用lodop打印插件
Sep 27 Javascript
ES6 fetch函数与后台交互实现
Nov 14 Javascript
Angular4.0动画操作实例详解
May 10 Javascript
学习LayUI时自研的表单参数校验框架案例分析
Jul 29 Javascript
vue 解决provide和inject响应的问题
Nov 12 Javascript
javascript滚轮控制模拟滚动条
Oct 19 #Javascript
Vue.js绑定HTML class数组语法错误的原因分析
Oct 19 #Javascript
微信小程序 教程之wxapp视图容器 swiper
Oct 19 #Javascript
微信小程序 教程之wxapp视图容器 scroll-view
Oct 19 #Javascript
微信小程序 教程之wxapp 视图容器 view
Oct 19 #Javascript
jQuery插件ajaxFileUpload使用实例解析
Oct 19 #Javascript
使用Angular.js开发的注意事项
Oct 19 #Javascript
You might like
php封装的smarty类完整实例
2016/10/19 PHP
php xhprof使用实例详解
2019/04/15 PHP
php中字符串和整数比较的操作方法
2019/06/06 PHP
Laravel基础_关于view共享数据的示例讲解
2019/10/14 PHP
采用CSS和JS,刚好我最近有个站点要用到下拉菜单!
2006/06/26 Javascript
js中通过父级进行查找定位元素
2014/06/15 Javascript
图解JavaScript中的this关键字
2020/05/28 Javascript
基于jquery实现表格内容筛选功能实例解析
2016/05/09 Javascript
Vue.js每天必学之表单控件绑定
2016/09/05 Javascript
细数JavaScript 一个等号,两个等号,三个等号的区别
2016/10/09 Javascript
jQ处理xml文件和xml字符串的方法(详解)
2016/11/22 Javascript
如何实现星星评价(jquery.raty.js插件)
2016/12/21 Javascript
JS按钮闪烁功能的实现代码
2017/07/21 Javascript
JavaScript使用Ajax上传文件的示例代码
2017/08/10 Javascript
JavaScript中.min.js和.js文件的区别讲解
2019/02/13 Javascript
JS实现提示效果弹出及延迟隐藏的功能
2019/08/26 Javascript
Typescript的三种运行方式(小结)
2019/09/18 Javascript
javascript Canvas动态粒子连线
2020/01/01 Javascript
JS数组及对象遍历方法代码汇总
2020/06/16 Javascript
[44:50]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第二局
2016/02/26 DOTA
Python实现更改图片尺寸大小的方法(基于Pillow包)
2016/09/19 Python
python3+mysql查询数据并通过邮件群发excel附件
2018/02/24 Python
利用pandas进行大文件计数处理的方法
2018/07/25 Python
python 二维矩阵转三维矩阵示例
2019/11/30 Python
python与idea的集成的实现
2020/11/20 Python
联想法国官方网站:Lenovo法国
2018/10/18 全球购物
韩国保养品、日本药妆购物网:小三美日
2018/12/30 全球购物
说出你对remoting 和webservice的理解和应用
2014/06/08 面试题
广播电视新闻学专业应届生求职信
2013/10/08 职场文书
会计应届生的自荐信
2013/12/13 职场文书
运动会广播稿80字
2014/01/23 职场文书
大学生职业规划书的范本
2014/02/18 职场文书
2014国庆节商场促销活动策划方案
2014/09/16 职场文书
上课玩手机的检讨书
2014/10/01 职场文书
MySQL学习总结-基础架构概述
2021/04/05 MySQL
springboot读取nacos配置文件
2022/05/20 Java/Android