之前写了一篇 《如何优雅的使用 Angular 表单验证》,结尾处介绍了统一验证反馈的类库 ngx-validator
,由于这段时间一直在新模块做微前端以及相关业务组件库,工具等开发,一直拖到现在,目前正式版 1.0 终于可以发布了。
可能有些人没有阅读过那篇博客,我这里简单介绍下 ngx-validator 主要的功能。
- 统一验证规则和错误反馈策略,通过响应式(配置的方式)设置每个元素对应每个验证器的错误提示文案以及统一错误信息反馈,避免手动写重复的模版实现错误提示,让开发人员专心写业务即可;
- 扩展一些 Angular 本身没有提供验证器和模版驱动的验证指令,比如
ngxUniqueCheck
、ngxMax
、ngxMin
; - 支持模版驱动和响应式驱动表单的验证。
从上次 0.0.1 版本到 1.0.0 正式发布新增了的功能有:
- 新增了
validateOn
支持submit
和blur
光标移走验证,之前只有点击按钮提交才会验证 - 对响应式表单支持的完善;
- 测试和 Demo 的完善;
- 重构了代码,添加了自动生成 changelog 和 husky 钩子做 commit message 规范检查和自动格式化(这些和库的功能无关,与开发者有关)
如果你不想听我废话,可以直接看 示例 ,其中包括模版驱动和响应式驱动表单实现验证的全部代码。
在你的项目中执行命令 npm install @why520crazy/ngx-validator --save
进行模块的安装
在启动模块 AppModule 中直接引入 NgxValidatorModule
,当然引入的时候可以通过 NgxValidatorModule.forRoot
进行一些全局参数的配置,配置包含全局的验证错误信息,错误反馈方式,目前反馈方式支持 boostrap4 的表单错误样式和 noop(什么都不提示),当然你可以扩展自己的错误反馈策略。
import { NgxValidatorModule, ValidationFeedbackStrategyBuilder } from '@why520crazy/ngx-validator';
@NgModule({
imports: [
CommonModule,
NgxValidatorModule.forRoot({
validationFeedbackStrategy: ValidationFeedbackStrategyBuilder.bootstrap(),
validationMessages: {
username: {
required: 'Username is required.',
pattern: 'Incorrect username format.'
}
}
})
]
})
class AppModule {}
在 form 表单元素上添加 ngxFormValidator
指令,配置的参数和全局配置的参数类似,此处单独配置只会对当前 Form 有效。
由于 ngxFormValidator
采用的验证器,以及元素是否验证通过完全读取的是 Angular 表单提供的信息,所以模版驱动表单必须遵循 Angular 表单的一些规则:
- 表单元素必须设置一个 name,这个 name 会和
ngForm controls
中的对象对应; - 表单元素必须设置
ngModel
,当提交表单时通过 ngModel 这只的变量获取用户输入的数据; - 验证器直接设置到表单元素上,比如 Angular 内置的
required
、email
、pattern
、maxlength
、minlength
以及 ngx-validator 类库提供的ngxMax
、ngxMin
、ngxUniqueCheck
。
最后在提交按钮上绑定 ngxFormSubmit
事件,当按钮点击后会触发表单验证,验证不通过会根据每个表单元素配置的提示信息反馈错误,如果使用的默认的 bootstrap4 的反馈策略,会在表单元素上加 is-invalid
class 样式,同时在表单元素后追加 <div class="invalid-feedback">{相关的错误提示信息}</div>
<form name="exampleForm" [ngxFormValidator]="validatorConfig">
<div class="form-group">
<label for="email1">Email address</label>
<input type="email" email class="form-control" name="email" id="email1"
[(ngModel)]="model.email" required placeholder="Enter email" />
</div>
<button type="button" (ngxFormSubmit)="submit()" class="btn btn-primary">Submit</button>
<form>
响应式表单验证和模版驱动类似,区别就是不需要给每个元素加 ngModel 和 验证器,直接使用 formControlName
指令指定名称, 然后在组件中通过 FormBuilder
生成 group 即可,基本没有特殊配置,参考 Angular 官网的响应式表单验证示例即可。
属性名 | 类型 | 备注 |
---|---|---|
validationMessages | {[controlName: string]: {[validatorErrorKey: string]: string}} | 表单元素验证规则 |
validationFeedbackStrategy | ValidationFeedbackStrategy | 没有配置,以全局配置的验证反馈策略为主 |
validateOn | 'submit' | 'blur' | 没有配置,以全局配置的 validateOn 为主 |
validatorConfig: NgxValidatorConfig = {
validationMessages: {
username: {
required: '用户名不能为空',
pattern: '用户名格式不正确,以字母,数字,下划线组成,首字母不能为数字,必须是2-20个字符',
ngxUniqueCheck: '输入的用户名已经存在,请重新输入'
}
},
validateOn: 'submit'
};
全局配置可以通过引入 NgxValidatorModule.forRoot(config)
进行设置,也可以在运行时注入 NgxValidatorLoader
服务进行配置
属性名 | 类型 | 备注 |
---|---|---|
validationMessages | {[controlName: string]: {[validatorErrorKey: string]: string}} | 表单元素验证规则 |
validationFeedbackStrategy | ValidationFeedbackStrategy | 默认以 bootstrap 4 的表单错误提示展示 |
globalValidationMessages | {[validatorErrorKey: string]: string} | 每个验证器全局的默认验证规则 |
validateOn | 'submit' | 'blur' | 触发验证,是提交触发验证还是光标移走触发验证 |
globalValidationMessages
默认规则如下,当某个表单元素比如 username
在表单和全局的 validationMessages
都没有被设置,验证不通过会直接显示 globalValidationMessages 中的 required
提示信息
{
required: '该选项不能为空',
maxlength: '该选项输入值长度不能大于{requiredLength}',
minlength: '该选项输入值长度不能小于{requiredLength}',
ngxUniqueCheck: '输入值已经存在,请重新输入',
email: '输入邮件的格式不正确',
repeat: '两次输入不一致',
pattern: '该选项输入格式不正确',
number: '必须输入数字',
url: '输入URL格式不正确',
max: '该选项输入值不能大于{max}',
min: '该选项输入值不能小于{min}'
};
- 单独验证某一个表单元素, 获取到
NgxFormValidatorDirective
实例ngxFormValidator: NgxFormValidatorDirective
,通过调用ngxFormValidator.validator.validateControl(name: string)
方法单独验证; - 根据服务端返回的错误,设置某个表单元素错误提示信息,调用
ngxFormValidator.validator.markControlAsError(name: string, errorMessage: string)
如果你的项目不是使用 bootstrap4,而是其他 UI 库,那么可以通过扩展自己的错误反馈策略,然后在全局设置中配置一次后所有的表单验证都会使用配置之后的策略,以下是一个自定义反馈策略的示例:
const CUSTOM_INVALID_CLASS = 'custom-invalid';
const CUSTOM_INVALID_FEEDBACK_CLASS = 'custom-invalid-feedback';
export class CustomValidationFeedbackStrategy implements ValidationFeedbackStrategy {
showError(element: HTMLElement, errorMessages: string[]): void {
element.classList.add(CUSTOM_INVALID_CLASS);
// add element show error message
}
removeError(element: HTMLElement): void {
element.classList.remove(CUSTOM_INVALID_CLASS);
// remove element error message
}
}