未加星标

Angular2表单-自定义验证器

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

在之前的两篇文章中,介绍了 Angular2的模板驱动的表单 和模型驱动表单,我们介绍了如何在页面和组件中添加验证器,以及如何判断验证器的结果等。在这里,我们就来看看怎样实现一个自定义的验证器。

目标

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


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 [email protected]/forms'; exportfunctionvalidateMobile(c: FormControl){ letMOBILE_REGEXP =/^1[0-9]{10,10}$/; returnMOBILE_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'; exportclassReactiveFormsComponentimplementsOnInit{ 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元素创建的,那么使用自定义的验证器就稍微麻烦一点。

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

<inputtype="text"name="mobile"[(ngModel)]="user.mobile"#mobile="ngModel"requiredminlength="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]' }) exportclassMobileValidator{}

这段代码很简单,就是用 @Directive 标签定义了一个指令 MobileValidator ,它作用的元素是同时具有 validateMobile 和 ngModel 属性的元素。这样,我们就可以在手机号的元素上添加一个属性,来使这个验证器指令起作用。

然后,我们还需要Angular的验证器框架能够调用我们的验证方法,这就需要 NG_VALIDATORS 。我们修改上面的验证器的指令定义如下:

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

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

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

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

<inputtype="text"name="mobile"[(ngModel)]="user.mobile"#mobile="ngModel"requiredminlength="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>

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: ReactJava服务器
分页:12
转载请注明
本文标题:Angular2表单-自定义验证器
本站链接:http://www.codesec.net/view/484882.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(183)