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 相关文章推荐
javascript 解决表单仍然提交即使监听处理函数返回false
Mar 14 Javascript
基于jquery 的一个progressbar widge
Oct 29 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
Feb 13 Javascript
js动态添加onclick事件可传参数与不传参数
Jul 29 Javascript
jQuery Validate插件实现表单强大的验证功能
Dec 18 Javascript
jQuery实现滚动条滚动到子元素位置(方便定位)
Jan 08 Javascript
小程序使用wxs解决wxml保留2位小数问题
Dec 13 Javascript
vue中解决拖拽改变存在iframe的div大小时卡顿问题
Jul 22 Javascript
vue 通过绑定事件获取当前行的id操作
Jul 27 Javascript
解决vue中axios设置超时(超过5分钟)没反应的问题
Sep 04 Javascript
js 图片懒加载的实现
Oct 21 Javascript
使用react-virtualized实现图片动态高度长列表的问题
May 28 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
冰滴咖啡制作步骤
2021/03/03 冲泡冲煮
PHP魔术方法__GET、__SET使用实例
2014/11/25 PHP
php+Mysqli利用事务处理转账问题实例
2015/02/11 PHP
利用php-cli和任务计划实现订单同步功能的方法
2017/05/03 PHP
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
2011/01/06 Javascript
javascript操作JSON的要领总结
2012/12/09 Javascript
JavaScript中prototype为对象添加属性的误区介绍
2013/10/15 Javascript
JS刷新当前页面的几种方法总结
2013/12/24 Javascript
在JS数组特定索引处指定位置插入元素的技巧
2014/08/24 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
2015/03/04 Javascript
jQuery实现自定义checkbox和radio样式
2015/07/13 Javascript
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
JavaScript基本语法学习教程
2016/01/14 Javascript
正则表达式替换html元素属性的方法
2016/11/26 Javascript
nodejs微信扫码支付功能实现
2018/02/17 NodeJs
详解react阻止无效重渲染的多种方式
2018/12/11 Javascript
layer.alert自定义关闭回调事件的方法
2019/09/27 Javascript
Python和php通信乱码问题解决方法
2014/04/15 Python
介绍Python的Django框架中的静态资源管理器django-pipeline
2015/04/25 Python
详解Python中的__getitem__方法与slice对象的切片操作
2016/06/27 Python
使用python读取txt文件的内容,并删除重复的行数方法
2018/04/18 Python
解决Python命令行下退格,删除,方向键乱码(亲测有效)
2020/01/16 Python
Django自定义YamlField实现过程解析
2020/11/11 Python
使用CSS3制作倾斜导航条和毛玻璃效果
2017/09/12 HTML / CSS
浅谈HTML5中dialog元素尝鲜
2018/10/15 HTML / CSS
美国紧身牛仔裤品牌:NYDJ
2017/05/24 全球购物
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
枚举和一组预处理的#define有什么不同
2016/09/21 面试题
外企测试工程师面试题
2015/02/01 面试题
优秀毕业生推荐信
2013/11/02 职场文书
家佳咖啡店创业计划书
2013/12/27 职场文书
贷款承诺书
2015/01/20 职场文书
歌舞青春观后感
2015/06/10 职场文书
2019毕业典礼主持词!
2019/07/05 职场文书
python实现手机推送 代码也就10行左右
2022/04/12 Python
科学家研发出新型速效酶,可在 24 小时内降解塑料制品
2022/04/29 数码科技