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. ...
随机推荐
- hadoop上C++开发两种方式的例子
百度在使用Hadoop过程中同样发现了Hadoop因为Java语言带来的低效问题,并对Hadoop进行扩展. 而在此之前,百度也尝试了 Hadoop PIPES 和 Hadoop Streamming ...
- [前端]Emmet 基本语法快查
Emmet 是一种快速写html的语法,通过几个简单的缩写,就可以拓展成html标签,工作中写html多多少少会有一些,使用的语法都是基础语法,这里总结下最常用的几个,备查. 这个插件支持非常多的ID ...
- 仿百度壁纸客户端(六)——完结篇之Gallery画廊实现壁纸预览已经项目细节优化
仿百度壁纸客户端(六)--完结篇之Gallery画廊实现壁纸预览已经项目细节优化 百度壁纸系列 仿百度壁纸客户端(一)--主框架搭建,自定义Tab + ViewPager + Fragment 仿百度 ...
- 高斯混合模型和EM算法
使用期望最大化算法(Expectation-Maximization)来进行密度估计(density estimation). 与k-means一样,给定的训练样本是,我们将隐含类别标签用表示.与k- ...
- html5 jqueryrotate插件实现旋转动画
CSS3 提供了多种变形效果,比如矩阵变形.位移.缩放.旋转和倾斜等等,让页面更加生动活泼有趣,不再一动不动.然后 IE10 以下版本的浏览器不支持 CSS3 变形,虽然 IE 有私有属性滤镜(fil ...
- OpenCV——马赛克
具体的算法可以参考: PS 滤镜 马赛克 // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_ ...
- TCP连接建立系列 — 服务端接收SYN段
本文主要分析:服务器端接收到SYN包时的处理路径. 内核版本:3.6 Author:zhangskd @ csdn blog 接收入口 1. 状态为ESTABLISHED时,用tcp_rcv_esta ...
- Unity Socket UDP
using System.Collections; using System.Collections.Generic; using System.Net.Sockets; using System.N ...
- Mina源码阅读笔记(六)—Mina异步IO的实现IoFuture
IoFuture是和IoSession紧密相连的一个类,在官网上并没有对它的描述,因为它一般不会显示的拿出来用,权当是一个工具类被session所使用.当然在作用上,这个系列可并不简单,我们先看源码的 ...
- WebApplicationContext初始化
Spring 提供了用于启动WebApplicaionContext的Web容器监听器. 通过Web容器监听器引导: <!-- 1 指定配置文件 --> <context-param ...