Angular 支持非常强大的内置表单验证,maxlength、minlength、required 以及 pattern。使用 Angular 的内置表单校验能够完成绝大多数的业务场景的校验需求,但有时我们还需要实现更为复杂的表单校验功能,这时可以使用 Angular 提供的表单自定义校验(Custom Validator)。下面,我们就来了解一下如何使用 Angular 的自定义表单校验
效果图:
1、首先,来创建我们的注册组件(register),并在模版中显示一个简单的表单
Angular 支持非常强大的内置表单验证,maxlength、minlength、required 以及 pattern。使用 Angular 的内置表单校验能够完成绝大多数的业务场景的校验需求,但有时我们还需要实现更为复杂的表单校验功能,这时可以使用 Angular 提供的表单自定义校验(Custom Validator)。下面,我们就来了解一下如何使用 Angular 的自定义表单校验
效果图:
1、首先,来创建我们的注册组件(register),并在模版中显示一个简单的表单
为了使表单看上去能够漂亮一些,在 index.html 中引入 bootstrap 样式文件:
2、接下来确定我们的验证需求:
我们希望用户名只能包含数字、字母和下划线,且不能以下划线开头
首先为 form 标签添加 formGroup 指令:
并且为 input 标签添加 formControlName 指令:
3、在代码中定义验证规则:
从内置表单模块中导入以下类:
其中:
1. formBuilder 用来构建表单数据 2. formGroup 表示表单类型 3. Validators 包含了表单内置的验证规则,如: Validators.required
registerForm: FormGroup;
定义表单验证不通过时每一项显示的错误消息(目前我们只有 username )
为每一项验证规则定义验证失败时的说明文字(表单控件可能有多条验证规则,由不通过的验证说明构成一条错误消息)
// 遍历错误消息对象
for (const field in this.formErrors) {
// 清空当前的错误消息
this.formErrors[field] = '';
// 获取当前表单的控件
const control = form.get(field);
// 当前表单存在此空间控件 && 此控件没有被修改 && 此控件验证不通过
if (control && control.dirty && !control.valid) {
// 获取验证不通过的控件名,为了获取更详细的不通过信息
const messages = this.validationMessage[field];
// 遍历当前控件的错误对象,获取到验证不通过的属性
for (const key in control.errors) {
// 把所有验证不通过项的说明文字拼接成错误消息
this.formErrors[field] += messages[key] + '\n';
}
}
}
}
下面只需要在表单构建结束后初始化错误消息,并且在每次表单数据更改时更新错误消息就可以了
// 初始化错误信息
this.onValueChanged();
此时,我们已经很好的控制了错误信息,下面只需要在表单模版中添加错误信息的显示就可以了
现在我们就可以尝试运行了,在代码不报错的情况下已经能够看到非常好的效果了
如果代码报错或没有出现想象中的效果则可以参照本文结尾的完整代码进行修改
4、虽然我们已经搭建了整个布局,但是还没有实现我们的最终目的:实现自定义的表单验证 接下来我们创建一个正则验证器,新建文件 validate-register.ts :
OK ! 大功告成了,赶紧运行代码尝试一下吧,我们可以随时添加各种验证规则,只需要修改 validationMessage 属性和 buildForm 方法即可!
如果添加多个表单控件的话还需要修改 formErrors,例如添加 password 控件则修改 formErrors 为
大家可自行尝试一下!
register.component.html
<form [formGroup]="registerForm" >
<div class="form-group">
<label for="username">用户名:
<input formControlName="username"
type="text" id="username" #username
class="form-control" >
<div *ngIf="formErrors.username" class="showerr alert alert-danger" >{{ formErrors.username }}
register.component.css:
register.component.ts:
// 定义表单
registerForm: FormGroup;
// 表单验证不通过时显示的错误消息
formErrors = {
username: ''
};
// 为每一项表单验证添加说明文字
validationMessage = {
'username': {
'minlength': '用户名长度最少为3个字符','only': '用户名只能包含数字、字母、下划线'
}
};
// 添加 fb 属性,用来创建表单
constructor(private fb: FormBuilder) { }
ngOnInit() {
// 初始化时构建表单
this.buildForm();
}
// 构建表单方法
buildForm(): void {
// 通过 formBuilder构建表单
this.registerForm = this.fb.group({
/* 为 username 添加3项验证规则:
// 每次表单数据发生变化的时候更新错误信息
this.registerForm.valueChanges
.subscribe(data => this.onValueChanged(data));
// 初始化错误信息
this.onValueChanged();
}
// 每次数据发生改变时触发此方法
onValueChanged(data?: any) {
// 如果表单不存在则返回
if (!this.registerForm) return;
// 获取当前的表单
const form = this.registerForm;
// 遍历错误消息对象
for (const field in this.formErrors) {
// 清空当前的错误消息
this.formErrors[field] = '';
// 获取当前表单的控件
const control = form.get(field);
// 当前表单存在此空间控件 && 此控件没有被修改 && 此控件验证不通过
if (control && control.dirty && !control.valid) {
// 获取验证不通过的控件名,为了获取更详细的不通过信息
const messages = this.validationMessage[field];
// 遍历当前控件的错误对象,获取到验证不通过的属性
for (const key in control.errors) {
// 把所有验证不通过项的说明文字拼接成错误消息
this.formErrors[field] += messages[key] + '\n';
}
}
}
}
}
validate-register.ts: