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 相关文章推荐
js类中的公有变量和私有变量
Jul 24 Javascript
js中判断Object、Array、Function等引用类型对象是否相等
Aug 29 Javascript
extjs 04_grid 单击事件新发现
Nov 27 Javascript
javascript的parseFloat()方法精度问题探讨
Nov 26 Javascript
浅谈页面装载js及性能分析方法
Dec 09 Javascript
jQuery学习笔记之基础中的基础
Jan 19 Javascript
angular实现表单验证及提交功能
Feb 01 Javascript
JavaScript文件的同步和异步加载的实现代码
Aug 19 Javascript
Node.js中的cluster模块深入解读
Jun 11 Javascript
vue.js 实现输入框动态添加功能
Jun 25 Javascript
微信小程序实现发送验证码按钮效果
Dec 20 Javascript
jQuery实现根据身份证号获取生日、年龄、性别等信息的方法
Jan 09 jQuery
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
合格的PHP程序员必备技能
2015/11/13 PHP
关于可运行代码无法正常执行的使用说明
2010/05/13 Javascript
jquery 隐藏与显示tr标签示例代码
2014/06/06 Javascript
javascript实现滑动解锁功能
2014/12/31 Javascript
基于jquery实现的树形菜单效果代码
2015/09/06 Javascript
BootStrap Fileinput的使用教程
2016/12/30 Javascript
Angular2+国际化方案(ngx-translate)的示例代码
2017/08/23 Javascript
vue v-model动态生成详解
2018/06/30 Javascript
详解vue中使用微信jssdk
2019/04/19 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
2019/09/29 Javascript
vue 项目打包时样式及背景图片路径找不到的解决方式
2019/11/12 Javascript
在Django的session中使用User对象的方法
2015/07/23 Python
Python中的模块导入和读取键盘输入的方法
2015/10/16 Python
Python编程实现微信企业号文本消息推送功能示例
2017/08/21 Python
基于python神经卷积网络的人脸识别
2018/05/24 Python
Python时间和字符串转换操作实例分析
2019/03/16 Python
Python比较配置文件的方法实例详解
2019/06/06 Python
python 在某.py文件中调用其他.py内的函数的方法
2019/06/25 Python
在python里面运用多继承方法详解
2019/07/01 Python
django如何自己创建一个中间件
2019/07/24 Python
python使用sklearn实现决策树的方法示例
2019/09/12 Python
python scipy卷积运算的实现方法
2019/09/16 Python
DJANGO-URL反向解析REVERSE实例讲解
2019/10/25 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
python爬虫多次请求超时的几种重试方法(6种)
2020/12/01 Python
使用css3绘制出各种几何图形
2016/08/17 HTML / CSS
九年级科学教学反思
2014/01/29 职场文书
《小儿垂钓》教学反思
2014/02/23 职场文书
司法局群众路线教育实践活动整改措施思想汇报
2014/10/13 职场文书
医院党的群众路线教育实践活动学习心得体会
2014/10/30 职场文书
2015年学校党建工作总结
2015/05/19 职场文书
2016年感恩父亲节活动总结
2016/04/01 职场文书
励志语录:时光飞逝,请学会珍惜所有的人和事
2020/01/16 职场文书
pandas中DataFrame数据合并连接(merge、join、concat)
2021/05/30 Python
【DOTA2】高能暴走TK秀!PSG LGD vs ASTER - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA
一文简单了解MySQL前缀索引
2022/04/03 MySQL