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获取统一管理的提示语(message)
Feb 03 Javascript
javascript对象的创建和访问
Mar 08 Javascript
JavaScript编写带旋转+线条干扰的验证码脚本实例
May 30 Javascript
jQuery解决$符号命名冲突
Jun 18 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
Aug 02 Javascript
jquery实现网页定位导航
Aug 23 Javascript
基于jquery实现的银行卡号每隔4位自动插入空格的实现代码
Nov 22 Javascript
JS实现加载时锁定HTML页面元素的方法
Jun 24 Javascript
vue实现菜单切换功能
May 08 Javascript
微信小程序身份证验证方法实现详解
Jun 28 Javascript
JS实现点击发送验证码 xx秒后重新发送功能
Jul 30 Javascript
vant时间控件使用方法详解
Dec 24 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
PHP版微信第三方实现一键登录及获取用户信息的方法
2016/10/14 PHP
使javascript也能包含文件
2006/10/26 Javascript
TBCompressor js代码压缩
2011/01/05 Javascript
jquery中ajax学习笔记4
2011/10/16 Javascript
javascript生成随机大小写字母的方法
2014/02/20 Javascript
JQuery的ON()方法支持的所有事件罗列
2015/02/28 Javascript
JS获取checkbox的个数简单实例
2016/08/19 Javascript
AngularJS入门教程之数据绑定原理详解
2016/11/02 Javascript
jQuery基于ajax方式实现用户名存在性检查功能示例
2017/02/10 Javascript
jQuery简单实现MD5加密的方法
2017/03/03 Javascript
手把手教你vue-cli单页到多页应用的方法
2018/05/31 Javascript
Node.js Stream ondata触发时机与顺序的探索
2019/03/08 Javascript
使用webpack编译es6代码的方法步骤
2019/04/28 Javascript
js 下拉菜单点击旁边收起实现(踩坑记)
2019/09/29 Javascript
npx create-react-app xxx创建项目报错的解决办法
2020/02/17 Javascript
vue+vant使用图片预览功能ImagePreview的问题解决
2020/04/10 Javascript
vue+canvas实现移动端手写签名
2020/05/21 Javascript
利用H5api实现时钟的绘制(javascript)
2020/09/13 Javascript
[01:19:46]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第一场 2月28日
2021/03/11 DOTA
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
Python实现删除时保留特定文件夹和文件的示例
2018/04/27 Python
对Python3中的print函数以及与python2的对比分析
2018/05/02 Python
详解Python中pyautogui库的最全使用方法
2020/04/01 Python
CSS3实现大小不一的粒子旋转加载动画
2016/04/21 HTML / CSS
健康监测猫砂:Pretty Litter
2017/05/25 全球购物
海飞丝的广告词
2014/03/20 职场文书
三年级班级文化建设方案
2014/05/04 职场文书
小学生我的梦想演讲稿
2014/08/21 职场文书
学习焦裕禄同志为人民服务思想汇报
2014/09/10 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
2015军训通讯稿大全
2015/07/18 职场文书
2016年大学生就业指导课心得体会
2015/10/09 职场文书
公司财务制度:成本管理控制制度模板
2019/11/19 职场文书
pyqt5打包成exe可执行文件的方法
2021/05/14 Python
用php如何解决大文件分片上传问题
2021/07/07 PHP
python接口测试返回数据为字典取值方式
2022/02/12 Python