Angular实现模版驱动表单的自定义校验功能(密码确认为例)


Posted in Javascript onMay 17, 2018

HTML5原生的表单校验属性(必填,长度限制,取值间隔,正则表达式等等)可以满足普通的校验需求,但是有些场景必须用到自定义校验,比如注册时的密码确认,有比对关系的时间/数值选择, 需要到请求到服务端取值验证等等···这里以密码确认为例进行说明。

指令开发

表单的验证状态是通过 formContro l的 errors 属性反馈出来的,所以基本的思路肯定就是需要添加校验规则,然后将验证结果添加到formControl实例的errors属性中。那么问题来了,模版驱动表单的控制都是在HTML模版中完成的,无法直接接触到 formControl实例。这个时候就需要使用指令了,将检验规则进行包装。Angular提供了 验证器供应商 NG_VALIDATORS ,用于处理表单自定义校验。先创建指令。

import { Directive} from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl} from '@angular/forms';
@Directive({
 selector: '[appConfirmpsw]',
 providers: [{
  provide : NG_VALIDATORS,
  useExisting : ConfirmpswDirective,
  multi: true
 }]
})
export class ConfirmpswDirective implements Validator {
 constructor() {
  }
 validate(control: AbstractControl): {[key: string]: any} {
   //检验规则
 }
}

1、为指令指定供应商  NG_VALIDATORS , 和别名类 ConfirmpswDirective , 及 multi 为true(可以用同一个token,注册不同的 provide)。因为是在 NG_VALIDATORS 提供商中注册的指令,所以才能被Angular的验证流程识别,需要注意的是要用useExisting来注册,这样就不会创建一个新的实例。

2、用 Validator接口来约束 自定义的指令,这是Angular提供的验证器的类 。有validate属性,会传入表单的formControl,返回 ValidationErrors 对象。

现在指令结构完成,开始进行校验部分。首先需要传入已输入的密码,所以增加@input,再指定校验规则,判断绑定表单的值和传入的已输入值是否相同

@Input('appConfirmpsw') confirmpsw: string;

为了避免使用指令时,还需要额外传入confirmpsw属性 ( <input type="password" appConfirmpsw  [confirmpsw]="'xxx'" >),所以我们将 指令名称appConfirmpsw作为confirmpsw的别名,这样传值会比较方便,简化为  <input type="password" [appConfirmpsw] = "'xxx'">

这里专门写一个检验函数,用来比对值和返回结果。记得在指令的validate中调用一下

export function comfirmPswValidator(_confirmpsw: string): ValidatorFn { //传入已输入的密码值 , 返回一个ValidatorFn
 return (control: AbstractControl): {[key: string]: any} => { //传入绑定表单的formControl
  if ( !control.value ) { //如果绑定未输入值,则返回 required错误
   return { 'required' : true };
  }
//如果两次输入的值不相同,则返回confirmpsw的错误
  return control.value !== _confirmpsw ? {'confirmpsw' : {value: true}} : null;
 };
}

完整指令如下:

import { Directive, Input } from '@angular/core';
import { NG_VALIDATORS, Validator, AbstractControl, ValidatorFn} from '@angular/forms';

@Directive({
 selector: '[appConfirmpsw]',
 providers: [{
  provide : NG_VALIDATORS,
  useExisting : ConfirmpswDirective,
  multi: true
 }]
})
export class ConfirmpswDirective implements Validator {

 @Input('appConfirmpsw') confirmpsw: string;
 constructor() {

  }
 validate(control: AbstractControl): {[key: string]: any} {
  console.log(this.confirmpsw);
  return this.confirmpsw ? comfirmPswValidator(this.confirmpsw)(control) : null;
 }
}

export function comfirmPswValidator(_confirmpsw: string): ValidatorFn {
 return (control: AbstractControl): {[key: string]: any} => {
  if ( !control.value ) {
   return { 'required' : true };
  }
  return control.value !== _confirmpsw ? {'confirmpsw' : {value: true}} : null;
 };
}

 使用

测试一下指令的效果吧

<div class="input-group">
   <label class="group-label" for="psw-new"> 新密码 :</label>
   <input class="group-input" [(ngModel)]="inputpsw.new" #new="ngModel" type="password" name="psw" id="psw-new" required>
  </div>
  <div class="input-group input-error" *ngIf="new.touched&&new.invalid">
   <div class="group-error-content" *ngIf="new.errors?.required">确认密码为必填项!</div>
  </div>
  <div class="input-group">
   <label class="group-label" for="psw-confirm">确认密码 :</label>
   <input class="group-input" [(ngModel)]="inputpsw.confirm" #confirm="ngModel" type="password" name="confirm" id="psw-confirm"
   [appConfirmpsw] = "new.value" required>
  </div>
  <div class="input-group input-error" *ngIf="confirm.touched&&confirm.invalid">
   <div class="group-error-content" *ngIf="confirm.errors?.required">新密码为必填项!</div>
   <div class="group-error-content" *ngIf="confirm.errors?.confirmpsw">密码输入不一致!</div>
  </div>

传入new表单的值,并通过errors.confirmpsw属性来控制提示语反馈。密码输入不一致,可以正确的校验到

Angular实现模版驱动表单的自定义校验功能(密码确认为例)

确认密码为空时的提示也正确

Angular实现模版驱动表单的自定义校验功能(密码确认为例)

总结

以上所述是小编给大家介绍的Angular实现模版驱动表单的自定义校验功能(密码确认为例),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
用javascript实现的支持lrc歌词的播放器
May 17 Javascript
jQuery动态添加 input type=file的实现代码
Jun 14 Javascript
Javascript查询DBpedia小应用实例学习
Mar 07 Javascript
js使浏览器窗口最大化实现代码(适用于IE)
Aug 07 Javascript
JQuery文本改变触发事件如聚焦事件、失焦事件
Jan 15 Javascript
JavaScript实现彩虹文字效果的方法
Apr 16 Javascript
javascript实现漂亮的拖动层,窗口拖拽特效
Apr 24 Javascript
在web中js实现类似excel的表格控件
Sep 01 Javascript
vue二级路由设置方法
Feb 09 Javascript
js中实例与对象的区别讲解
Jan 21 Javascript
基于vue+element实现全局loading过程详解
Jul 10 Javascript
原生JavaScript实现简单五子棋游戏
Jun 28 Javascript
AngularJS自定义过滤器用法经典实例总结
May 17 #Javascript
JS 实现分页打印功能
May 16 #Javascript
使用vue-cli导入Element UI组件的方法
May 16 #Javascript
JS 使用 window对象的print方法实现分页打印功能
May 16 #Javascript
Koa2微信公众号开发之消息管理
May 16 #Javascript
js实现鼠标单击Tab表单切换效果
May 16 #Javascript
Koa2微信公众号开发之本地开发调试环境搭建
May 16 #Javascript
You might like
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
2015/10/10 PHP
ThinkPHP连接Oracle数据库
2016/04/22 PHP
PHP反射实际应用示例
2019/04/03 PHP
PHP面向对象程序设计中的self、static、parent关键字用法分析
2019/08/14 PHP
ExtJS扩展 垂直tabLayout实现代码
2009/06/21 Javascript
3Z版基于jquery的图片复选框(asp.net+jquery)
2010/04/12 Javascript
jQuery 源码分析笔记(7) Queue
2011/06/19 Javascript
js Html结构转字符串形式显示代码
2011/11/15 Javascript
js里怎么取select标签里的值并修改
2012/12/10 Javascript
JS格式化数字保留两位小数点示例代码
2013/10/15 Javascript
BootStrap selectpicker
2016/06/20 Javascript
js将滚动条滚动到指定位置的简单实现方法
2016/06/25 Javascript
jQuery学习笔记之入门
2016/12/14 Javascript
微信小程序教程系列之视图层的条件渲染(10)
2017/04/19 Javascript
bootstrap轮播模板使用方法详解
2017/11/17 Javascript
vue组件name的作用小结
2018/05/23 Javascript
JavaScript点击按钮生成4位随机验证码
2021/01/28 Javascript
python3.3使用tkinter开发猜数字游戏示例
2014/03/14 Python
Python-基础-入门 简介
2014/08/09 Python
Python通过future处理并发问题
2017/10/17 Python
python 根据时间来生成唯一的字符串方法
2019/01/14 Python
Python数据分析模块pandas用法详解
2019/09/04 Python
Python爬虫爬取糗事百科段子实例分享
2020/07/31 Python
详解python tkinter 图片插入问题
2020/09/03 Python
Python内存泄漏和内存溢出的解决方案
2020/09/26 Python
html5+css3之CSS中的布局与Header的实现
2014/11/21 HTML / CSS
微软英国官方网站:Microsoft英国
2016/10/15 全球购物
Shopty西班牙:缝纫机在线销售
2018/01/26 全球购物
奢华时尚的创新平台:Baltini
2020/10/03 全球购物
计算机求职信
2013/12/01 职场文书
简历的个人自我评价范文
2014/01/03 职场文书
舞蹈教师自荐信
2014/01/27 职场文书
《鱼游到了纸上》教学反思
2014/02/20 职场文书
小学安全汇报材料
2014/08/14 职场文书
2014年建筑工作总结
2014/11/26 职场文书
单位接收证明格式
2015/06/18 职场文书