Angular5+ 自定义表单验证器
程序员文章站
2022-06-24 16:22:41
Angular自定义表单验证器 - 怎样实现“再次输入密码”的验证(两个controller值相等)(equalTo) ......
angular5+ 自定义表单验证器
custom validators
标签(空格分隔): angular
首先阐述一下遇到的问题:
- 怎样实现“再次输入密码”的验证(两个controller值相等)(equalto)
- 怎样反向监听(先输入“再次输入密码”,后输入设置密码)
解决思路:
- 第一个问题,可以通过
[abstractcontrol].root.get([targetname])
来取得指定的controller,然后比较他们的值。 - 第二个,可以通过
[target].seterrors([errors])
来实现。
- 这是一个我的自定义表单验证:
import {abstractcontrol, formgroup, validatorfn} from '@angular/forms'; import {g} from '../services/data-store.service'; export class myvalidators { private static isemptyinputvalue(value) { // we don't check for string here so it also works with arrays return value == null || value.length === 0; } private static isemptyobject(obj) { if (typeof obj === 'object' && typeof obj.length !== 'number') { return object.keys(obj).length === 0; } return null; } /** * 等于指定controller的值 * @param targetname 目标的formcontrolname * @returns {(ctrl: formcontrol) => {equalto: {valid: boolean}}} */ static equalto(targetname: string): validatorfn { return (control: abstractcontrol): {[key: string]: any} | null => { const target = control.root.get(targetname); if (target === null) { return null; } if (this.isemptyinputvalue(control.value)) { return null; } return target.value === control.value ? null : {'equalto': { valid: false }}; }; } /** * 反向输入监听指定controller是否与当前值相等 * @param targetname */ static equalfor(targetname: string): validatorfn { return (control: abstractcontrol): {[key: string]: any} | null => { const target = control.root.get(targetname); if (target === null) { return null; } if (this.isemptyinputvalue(control.value)) { return null; } if (target.value === control.value) { const errors = target.errors; delete errors['equalto']; if (this.isemptyobject(errors)) { target.seterrors(null); } else { target.seterrors(errors); } return null; } target.seterrors({ 'equalto': { valid: false } }); }; } ... }
(注:)其中g.regex
等的是全局变量。
- 然后
formbuilder
来实现:
import { component, oninit } from '@angular/core'; import {eventsservice} from '../../../services/events.service'; import {formbuilder, formgroup, validators} from '@angular/forms'; import {g} from '../../../services/data-store.service'; import {fade} from '../../../animations/fade.animation'; import {myvalidators} from '../../../directives/my-validators.directive'; @component({ selector: 'app-sign-up', templateurl: './sign-up.component.html', styleurls: ['./sign-up.component.scss'], animations: [fade] }) export class signupcomponent implements oninit { signform: formgroup; // 表单组formgroup submitting: boolean; // 是否可以提交 validations = g.validations; constructor(private eventsservice: eventsservice, private formbuilder: formbuilder) { this.submitting = false; // this.init(); } ngoninit() { // 设置父组件标题 this.eventsservice.publish('setsign', { title: '注册', subtitle: { name: '立即登录', uri: '/account/sign-in' } }); } // 立即注册 onsubmit() { console.log(this.signform.getrawvalue()); } // 表单初始化 private init() { this.signform = this.formbuilder.group({ username: ['', validators.compose([validators.required, validators.maxlength(this.validations.usr_max)])], password: ['', validators.compose([ validators.required, validators.minlength(this.validations.pass_min), validators.maxlength(this.validations.pass_max), myvalidators.equalfor('passwordconfirm') ])], passwordconfirm: ['', validators.compose([ validators.required, validators.minlength(this.validations.pass_min), validators.maxlength(this.validations.pass_max), myvalidators.equalto('password') ])] }); } }
(注:)其中fade
动画效果。
- 然后在html模板中,显示表单验证提示信息:
<form [formgroup]="signform" (ngsubmit)="onsubmit()" class="sign-form" @fade> <!-- 账号 --> <div class="input-group username"> <span class="addon prev"><i class="civ civ-i-usr"></i></span> <input type="text" name="username" class="form-control form-control-left default" placeholder="请输入账号" formcontrolname="username" autocomplete="off"> <ul class="errors" *ngif="signform.get('username').invalid && (signform.get('username').dirty || signform.get('username').touched)"> <li *ngif="signform.get('username').haserror('required')" class="error"> 请输入您的账号! </li> <li *ngif="signform.get('username').haserror('maxlength')" class="error"> 账号不超过{{ validations.usr_max }}位! </li> </ul> </div> <!-- /.账号 --> <!-- 密码 --> <div class="input-group password"> <span class="addon prev"><i class="civ civ-i-lock"></i></span> <input type="password" name="password" class="form-control form-control-left default" placeholder="请输入密码" formcontrolname="password"> <ul class="errors" *ngif="signform.get('password').invalid && (signform.get('password').dirty || signform.get('password').touched)"> <li *ngif="signform.get('password').haserror('required')" class="error"> 请输入您的密码! </li> <li *ngif="signform.get('password').haserror('minlength')" class="error"> 请输入至少{{ validations.pass_min }}位数的密码! </li> <li *ngif="signform.get('password').haserror('maxlength')" class="error"> 密码不超过{{ validations.pass_max }}位! </li> </ul> </div> <!-- /.密码 --> <!-- 重复密码 --> <div class="input-group password-confirm"> <span class="addon prev"><i class="civ civ-i-lock"></i></span> <input type="password" name="passwordconfirm" class="form-control form-control-left default" placeholder="请再次输入密码" formcontrolname="passwordconfirm"> <ul class="errors" *ngif="signform.get('passwordconfirm').invalid && (signform.get('passwordconfirm').dirty || signform.get('passwordconfirm').touched)"> <li *ngif="signform.get('passwordconfirm').haserror('required')" class="error"> 请再次输入密码! </li> <li *ngif="signform.get('passwordconfirm').haserror('minlength')" class="error"> 请输入至少{{ validations.pass_min }}位数的密码! </li> <li *ngif="signform.get('passwordconfirm').haserror('maxlength')" class="error"> 密码不超过{{ validations.pass_max }}位! </li> <li *ngif="!signform.get('passwordconfirm').haserror('maxlength') && !signform.get('passwordconfirm').haserror('minlength') && signform.get('passwordconfirm').haserror('equalto')" class="error"> 两次密码输入不一致! </li> </ul> </div> <!-- /.重复密码 --> <!-- 提交按钮 --> <button type="submit" class="btn btn-primary btn-block submit" [disabled]="submitting || signform.invalid">立即注册</button> <!-- /.提交按钮 --> </form>
最后,我们可以看到,实现了想要的效果:
(附:)完整的自定义表单验证器:
import {abstractcontrol, formgroup, validatorfn} from '@angular/forms'; import {g} from '../services/data-store.service'; export class myvalidators { private static isemptyinputvalue(value) { // we don't check for string here so it also works with arrays return value == null || value.length === 0; } private static isemptyobject(obj) { if (typeof obj === 'object' && typeof obj.length !== 'number') { return object.keys(obj).length === 0; } return null; } /** * 等于指定controller的值 * @param targetname 目标的formcontrolname * @returns {(ctrl: formcontrol) => {equalto: {valid: boolean}}} */ static equalto(targetname: string): validatorfn { return (control: abstractcontrol): {[key: string]: any} | null => { const target = control.root.get(targetname); if (target === null) { return null; } if (this.isemptyinputvalue(control.value)) { return null; } return target.value === control.value ? null : {'equalto': { valid: false }}; }; } /** * 反向输入监听指定controller是否与当前值相等 * @param targetname */ static equalfor(targetname: string): validatorfn { return (control: abstractcontrol): {[key: string]: any} | null => { const target = control.root.get(targetname); if (target === null) { return null; } if (this.isemptyinputvalue(control.value)) { return null; } if (target.value === control.value) { const errors = target.errors; delete errors['equalto']; if (this.isemptyobject(errors)) { target.seterrors(null); } else { target.seterrors(errors); } return null; } target.seterrors({ 'equalto': { valid: false } }); }; } /** * 验证手机号 * @returns {(ctrl: formcontrol) => {mobile: {valid: boolean}}} */ static get mobile() { return (control: abstractcontrol) => { if (this.isemptyinputvalue(control.value)) { return null; } const valid = g.regex.mobile.test(control.value); return valid ? null : { 'mobile': { valid: false } }; }; } /** * 验证身份证 * @returns {(ctrl: formcontrol) => {idcard: {valid: boolean}}} */ static get idcard() { return (control: abstractcontrol) => { if (this.isemptyinputvalue(control.value)) { return null; } const valid = g.regex.id_card.test(control.value); return valid ? null : { 'idcard': { valid: false } }; }; } /** * 验证汉字 * @returns {(ctrl: formcontrol) => {cn: {valid: boolean}}} */ static get cn() { return (control: abstractcontrol) => { if (this.isemptyinputvalue(control.value)) { return null; } const valid = g.regex.cn.test(control.value); return valid ? null : { 'cn': { valid: false } }; }; } /** * 指定个数数字 * @param {number} length * @returns {(ctrl: formcontrol) => (null | {number: {valid: boolean}})} */ static number(length: number = 6) { return (control: abstractcontrol) => { if (this.isemptyinputvalue(control.value)) { return null; } const valid = new regexp(`^\\d{${length}}$`).test(control.value); return valid ? null : { 'number': { valid: false } }; }; } /** * 强密码(必须包含数字字母) * @returns {(ctrl: formcontrol) => (null | {number: {valid: boolean}})} */ static get strictpass() { return (control: abstractcontrol) => { if (this.isemptyinputvalue(control.value)) { return null; } const valid = g.regex.strict_pass.test(control.value); return valid ? null : { 'strictpass': { valid: false } }; }; } }
下一篇: 给初学ajax的人 ajax函数代码
推荐阅读
-
thinkPHP5框架自定义验证器实现方法分析
-
Angular2 自定义表单验证器的实现方法
-
Angular2表单自定义验证器的实现
-
vee-validate vue 2.0自定义表单验证的实例
-
Swagger UI改造 增加 Token验证、显示控制器注释、自定义泛型缓存应用、
-
Angular在模板驱动表单中自定义校验器的方法
-
Vue使用vux-ui自定义表单验证遇到的问题及解决方法
-
MVC身份验证.MVC过滤器.MVC6关键字Task,Async.前端模拟表单验证,提交.自定义匿名集合.Edge导出到Excel.BootstrapTree树状菜单的全选和反选.bootstrap可搜索可多选可全选下拉框
-
vue 表单验证自定义字段,特殊字符
-
Python装饰器、Django自定义登录验证