Angular使用总结 ---以密码确认为例实现模版驱动表单的自定义校验
上一篇 总结了模版驱动表单的基本用法,示例中的校验使用的是原生HTML5的校验方式,本文补上自定义校验的部分。
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支持表单的双向数据绑定,校验,状态管理等,总结下. 获取用户输入 <div class="container-fluid login-page&q ...
- SNF快速开发平台MVC-各种级联绑定方式,演示样例程序(包含表单和表格控件)
做了这么多项目,经常会使用到级联.联动的情况. 如:省.市.县.区.一级分类.二级分类.三级分类.仓库.货位. 方式:有表单需要做级联的,还是表格行上需要做级联操作的. 实现:实现方法也有很多种方式. ...
- Angular 表单(二) - 模板驱动表单
import { Component, OnInit } from '@angular/core'; import { Hero} from '../hero'; @Component({ selec ...
- Angular使用总结 --- 模型驱动表单
模型驱动表单 之前有篇博文总结了 模版驱动表单 , 以及 模版驱动表单的自定义校验 , 本篇总结下模型驱动表单. 与模版驱动表单是不同的编程思路,偏向于数据模型.先在组件中建立表单控件的对象树,再绑定 ...
- angular表单的使用实例
原文 https://www.jianshu.com/p/da1fd5396798 大纲 1.模板驱动表单的创建 2.响应式表单的创建 3.模板驱动型表单的自定义指令 4.响应式表单的自定义指令 5. ...
- angular表单知识点
原文 https://www.jianshu.com/p/c772d143e1fc 大纲 1.对表单的理解 2.模板驱动表单(Template Driven Forms) 3.响应式表单(Reacti ...
- Angular 表单验证类库 ngx-validator 1.0 正式发布
背景介绍 之前写了一篇 <如何优雅的使用 Angular 表单验证>,结尾处介绍了统一验证反馈的类库 ngx-validator ,由于这段时间一直在新模块做微前端以及相关业务组件库, ...
- Angular 2 + 折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点
前言 表单在整个系统中的作用相当重要,这里主要扯下响应表单的实现方式. 首先须要操作表单的模块引入这两个模块. import { FormsModule, ReactiveFormsModule } ...
- form表单的密码是否一致校验功能
这是form类表单,自定义的form表单,需要重写钩子函数 """ forms类表单 """ # 校验密码是否一致 from django. ...
随机推荐
- Python的time(时间戳与时间字符串互相转化)
strptime("string format")字符串如"20130512000000"格式的 输入处理函数 localtime(float a)时间戳的输入 ...
- Android Studio 1.2.2设置显示行号
Android Studio设置显示行号的方法与Eclipse有少许差别,直接在代码中右键,弹出右键菜单是没有显示行号功能的. 在Android Studio中设置方法有二: 1.临时显示行号 在单个 ...
- Java进阶(十八)Java实现定时器(Timer)
Java实现定时器(Timer) 绪 在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等.对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类.java.u ...
- 【一天一道LeetCode】 #3 Longest Substring Without Repeating Characters
一天一道LeetCode (一)题目 Given a string, find the length of the longest substring without repeating charac ...
- Developing User Interfaces
Developing a User Interface with ADF Faces Purpose This tutorial covers developing the user interf ...
- Altium Designer设计PCB板之“精神”
通过一小段时间的练习,感觉先领悟设计PCB板的“精神”更加重要.在这里,我指的“精神”是指PCB板中涉及的元器件原理图及其封装设计.当然,设计PCB板还有其他方面重要的精神需要掌握.本文所提到的“精神 ...
- Android高级控件(二)——SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现
Android高级控件(二)--SurfaceView实现GIF动画架包,播放GIF动画,自己实现功能的初体现 写这个的原因呢,也是因为项目中用到了gif动画,虽然网上有很多的架包可以实现,不过我们还 ...
- Socket层实现系列 — accept()的实现(二)
本文主要分析accept()的阻塞等待和唤醒. 内核版本:3.6 Author:zhangskd @ csdn blog 等待队列 (1)socket的等待队列 /* * @sk_wq: sock w ...
- Android特效专辑(三)——自定义不一样的Toast
Android特效专辑(三)--自定义不一样的Toast 大家都知道,Android的控件有时候很难满足我们的需求,所以我们需要自定义View.自定义的方式很多,有继承原生控件也有直接自定义View的 ...
- EventBus3.0 study
概述 eventbus出来很久了,最近想用一下eventbus,自己对着一些博客撸了一个demo,发现竟然crash了,然后去看看源码发现3.0的eventbus有了很多改动.技术变化真快,得保持谦虚 ...