在 Angular2 中实现自定义校验指令(确认密码)的方法
发布时间 - 2026-01-10 22:44:45 点击率:次我们会在本文中探索 Angular 2 内建的自定义验证。

# 介绍
Angular 2 原生就支持一些有用的验证器:
- required: 验证字段必须存在
- minlength: 验证字段值的最小长度有效
- maxlength: 验证字段值的最大长度有效
- pattern: 验证输入的值是否匹配给定的模板,比如 email
我们会基于下面的接口创建一个表单来获取用户信息。
// user.interface.ts
export interface User {
username: string; // required, must be 5-8 characters
email: string; // required, must be valid email format
password: string; // required, value must be equal to confirm password.
confirmPassword: string; // required, value must be equal to password.
}
需求
仅在字段数据不正确或提交表单的时候,为每个字段 显示错误消息 。
UI 展示:
# App 配置
这是我们的文件结构:
|- app/ |- app.component.html |- app.component.ts |- app.module.ts |- equal-validator.directive.ts |- main.ts |- user.interface.ts |- index.html |- styles.css |- tsconfig.json
为了使用新的表单模块,我们需要用 npm install @ angular/forms 指令调用 npm 包,并在应用程序模块中导入最新的表单模块。
$ npm install @angular/forms --save
下面是我们应用程序的 app.module.ts 模块:
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ], // import forms module here
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
})
export class AppModule { }
# App 组件
让我们继续创建 App 组件。
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { User } from './user.interface';
@Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent implements OnInit {
public user: User;
ngOnInit() {
// initialize model here
this.user = {
username: '',
email: '',
password: '',
confirmPassword: ''
}
}
save(model: User, isValid: boolean) {
// 调用API保存customer
console.log(model, isValid);
}
}
# HTML 视图
这是我们的 HTML 视图的样子。
<!-- app.component.html --> <div> <h1>Add user</h1> <form #f="ngForm" novalidate (ngSubmit)="save(f.value, f.valid)"> <!-- 我们将把验证的字段放在这里 --> <button type="submit" [disabled]="!myForm.valid">Submit</button> </form> </div>
现在来一个个添加控件。
用户名
需求: 必填,长度在 5-8 个字符之间
<!-- app.component.html -->
...
<div>
<label>Username</label>
<input type="text" name="username" [ngModel]="user.username"
required minlength="5" maxlength="8" #username="ngModel">
<small [hidden]="username.valid || (username.pristine && !f.submitted)">
Username is required (minimum 5 characters).
</small>
</div>
<pre *ngIf="username.errors">{{ username.errors | json }}</pre>
...
required、minlength、maxlength 都是内置的验证器,所以很容易使用。
我们只会在用户名无效、获得焦点和提交表单的情况下显示错误消息。最后一条的 pre 标签在开发过程中对调试很有用。它会显示字段的所有验证错误。
电子邮件地址
需求: 必填,必须是有效的电子邮件地址格式
<!-- app.component.html --> ... <div> <label>Email</label> <input type="email" name="email" [ngModel]="user.email" required pattern="^[a-zA-Z0–9_.+-]+@[a-zA-Z0–9-]+.[a-zA-Z0–9-.]+$" #email="ngModel" > <small [hidden]="email.valid || (email.pristine && !f.submitted)"> Email is required and format should be <i>john@doe.com</i>. </small> </div> ...
我们把 email 设置为必填,然后使用内建的模板验证器,通过正则表达式来检查 email 的值:^[a-zA-Z0–9_.+-]+@[a-zA-Z0–9-]+.[a-zA-Z0–9-.]+$.
密码和确认密码
需求:
- 密码: 必填,值必须与确认密码的值相同。
- 确认密码: 必填,值必须与密码的值相同。
<!-- app.component.html --> ... <div> <label>Password</label> <input type="password" name="password" [ngModel]="user.password" required #password="ngModel"> <small [hidden]="password.valid || (password.pristine && !f.submitted)"> Password is required </small> </div> <div> <label>Retype password</label> <input type="password" name="confirmPassword" [ngModel]="user.confirmPassword" required validateEqual="password" #confirmPassword="ngModel"> <small [hidden]="confirmPassword.valid || (confirmPassword.pristine && !f.submitted)"> Password mismatch </small> </div> ...
validateEqual 是我们自定义的验证器。它会将当前输入的值与输入的密码值进行对比验证。
# 自定义确认密码验证器
我们将制定一个 validate equal 指令。
// equal-validator.directive.ts
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
constructor( @Attribute('validateEqual') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {
// self value (e.g. retype password)
let v = c.value;
// control value (e.g. password)
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}
}
代码很长,让我们把它拆开一部分一部分地看。
申明指令
// equal-validator.directive.ts
@Directive({
selector: '[validateEqual][formControlName],[validateEqual]
[formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
首先,我们使用 @Directive 注解定义指令。然后我们指定 selector。selector 是必须的。我们会扩展内建验证器集合 NG_VALIDATORS 来将我们的等值验证器用于 providers.
// equal-validator.directive.ts
export class EqualValidator implements Validator {
constructor( @Attribute('validateEqual') public validateEqual: string) {}
validate(c: AbstractControl): { [key: string]: any } {}
}
我们的指令类必须实现 Validator 接口。Validator 接口需要 avalidate 函数。在构建函数中,我们通过 @Attribute('validateEqual') 注解注入属性值,并将其赋值给 validateEqual 变量。在我们的示例中, validateEqual 的值是 "password" 。
实现验证
// equal-validator.directive.ts
validate(c: AbstractControl): { [key: string]: any } {
// 自己的值 (如 retype password)
let v = c.value;
// 控件的值 (如 password)
let e = c.root.get(this.validateEqual);
// 值不等旱
if (e && v !== e.value) return {
validateEqual: false
}
return null;
}
首先我们从输入控件读入值,赋给 v。然后我们在表单中找到 password 控件的值赋值给 e。之后检查值是否相等,如果不等就返回错。
# 在应用模块中导入自定义验证器
要使用自定义验证器,需要先将其导入到应用程序模块中。
// app.module.ts
...
import { EqualValidator } from './equal-validator.directive'; // 导入验证器
import { AppComponent } from './app.component';
@NgModule({
imports: [ BrowserModule, FormsModule ],
declarations: [ AppComponent, EqualValidator ], // 导入到应用模块
bootstrap: [ AppComponent ],
})
...
好了!假如你在 password 字段中输入 "123",在 retype password 字段中输入"xyz",就会显示一个密码不匹配的错误。
# 看起来挺好,但是……
现在一切都挺好,直到你 在 retype passowrd 中输入文本之后 又修改了 password 字段的值。
比如,你在 password 字段中输入 "123",在 retype password 字段中也输入 "123", 然后将 password 字段的值改为 "1234" 。验证仍然通过。 为什么?
因为我们只把等值验证器应用到 retype password 字段。只有当 retype password 的值发生变化时才会触发验证。
解决办法
有几种方法可以解决这个问题。我们这里只讨论其中一种,你自己可以去找到其它办法。我们会再次使用 validateEqual 验证器并 添加 一个 reverse 属性。
<!-- app.component.html --> ... <input type="password" class="form-control" name="password" [ngModel]="user.password" required validateEqual="confirmPassword" reverse="true"> <input type="password" class="form-control" name="confirmPassword" [ngModel]="user.confirmPassword" required validateEqual="password"> ...
- reverse 是 false 或者没有设置的情况下,我们会像前一节提到的那样执行等值验证器。
- reverse 是 true 的时候,我们仍然会执行等值验证器,但它不会为当前控件添加错误消息,而是 为指定 会把的目标控件添加错误消息 。
在我们的例子中,我们设置 password 验证的 reverse 为 true。只要 password 与 retype password 的 值不等,我们会为确证密码字段添加一个错误消息,而不是重置 password 字段。
完整的自定义验证器代码如下:
// equal-validator.directive.ts
import { Directive, forwardRef, Attribute } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
@Directive({
selector: '[validateEqual][formControlName],[validateEqual][formControl],[validateEqual][ngModel]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EqualValidator), multi: true }
]
})
export class EqualValidator implements Validator {
constructor(@Attribute('validateEqual') public validateEqual: string,
@Attribute('reverse') public reverse: string) {
}
private get isReverse() {
if (!this.reverse) return false;
return this.reverse === 'true' ? true: false;
}
validate(c: AbstractControl): { [key: string]: any } {
// self value
let v = c.value;
// control vlaue
let e = c.root.get(this.validateEqual);
// value not equal
if (e && v !== e.value && !this.isReverse) {
return {
validateEqual: false
}
}
// value equal and reverse
if (e && v === e.value && this.isReverse) {
delete e.errors['validateEqual'];
if (!Object.keys(e.errors).length) e.setErrors(null);
}
// value not equal and reverse
if (e && v !== e.value && this.isReverse) {
e.setErrors({ validateEqual: false });
}
return null;
}
}
当然,还有其他方法也能解决密码和确认密码验证问题。有些人建议在组( stack overflow )中添加密码和确认密码的机制,然后验证它。
方法没有绝对的好与坏,适合自己的才是最好的。
以上所述是小编给大家介绍的在 Angular2 中实现自定义校验指令(确认密码)的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# angular
# 自定义校验
# 自定义指令
# angular4中关于表单的校验示例
# 详解AngularJs HTTP响应拦截器实现登陆、权限校验
# 微信+angularJS的SPA应用中用router进行页面跳转
# jssdk校验失败问题解决
# Angular短信模板校验代码
# 自定义
# 表单
# 必填
# 自己的
# 这是
# 内建
# 让我们
# 应用程序
# 你在
# 会在
# 挺好
# 小编
# 都是
# 情况下
# 导入到
# 就会
# 好了
# 放在
# 最好的
# 才是
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Python制作简易注册登录系统
Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中
Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】
如何打造高效商业网站?建站目的决定转化率
Laravel如何实现API版本控制_Laravel API版本化路由设计策略
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
如何在阿里云高效完成企业建站全流程?
Python进程池调度策略_任务分发说明【指导】
香港服务器建站指南:外贸独立站搭建与跨境电商配置流程
如何快速搭建自助建站会员专属系统?
Laravel如何实现多对多模型关联?(Eloquent教程)
java中使用zxing批量生成二维码立牌
如何在阿里云域名上完成建站全流程?
制作企业网站建设方案,怎样建设一个公司网站?
Android okhttputils现在进度显示实例代码
如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环
在线制作视频的网站有哪些,电脑如何制作视频短片?
Laravel如何优雅地处理服务层_在Laravel中使用Service层和Repository层
郑州企业网站制作公司,郑州招聘网站有哪些?
Laravel软删除怎么实现_Laravel Eloquent SoftDeletes功能使用教程
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
如何批量查询域名的建站时间记录?
Python文件流缓冲机制_IO性能解析【教程】
Python图片处理进阶教程_Pillow滤镜与图像增强
Laravel Blade模板引擎语法_Laravel Blade布局继承用法
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
如何用腾讯建站主机快速创建免费网站?
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
如何用景安虚拟主机手机版绑定域名建站?
猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】
Laravel中的Facade(门面)到底是什么原理
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
javascript中的try catch异常捕获机制用法分析
敲碗10年!Mac系列传将迎来「触控与联网」双革新
Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
韩国服务器如何优化跨境访问实现高效连接?
Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制
香港服务器租用每月最低只需15元?
手机软键盘弹出时影响布局的解决方法
HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】
Laravel如何实现API版本控制_Laravel版本化API设计方案
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)

