Angular2:验证表单而不在每次输入时定义错误消息?
我想在Angular2:验证表单而不在每次输入时定义错误消息?,angular,Angular,我想在angular2中验证表单。我学习了一些文档,它的定义如下: It will show following messages If field is empty : Field is mandatory If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as eas
angular2
中验证表单。我学习了一些文档,它的定义如下:
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
正在从服务器获取数据
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
需要用户名
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
您的用户名不能以数字开头
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
此用户名已获取
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
萨姆比特数据
构造函数(私有生成器:FormBuilder){
this.username=新控件(
"",
compose([Validators.required,UsernameValidator.startsWithNumber]),
UsernameValidator.UsernameTake
);
this.form=builder.group({
用户名:this.username
});
}
对于每个输入,我需要定义许多错误消息。我觉得不好。我想要像jquery.validate一样,我只定义
input
,错误消息将自动呈现,如下所示
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
要减少代码,一种方法是编写组件
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
它将处理所有的条件检查
和错误消息
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
带有组件的HTML将如下所示
export const errorConfiguration = {
'alphaNum': {
'regex': /^[a-zA-Z0-9 ]*$/,
'msg': 'LABEL should contain only alpaha numeric values'
},
'email': {
'regex': /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/,
'msg': 'LABEL is not valid email'
}
};
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
import { Directive, ElementRef, forwardRef, Input } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { errorConfiguration } from './error-configurations'; // use configuration file
@Directive({
selector: '[easyValidate]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EasyValidatorDirective), multi: true }
]
})
export class EasyValidatorDirective implements Validator {
@Input('easyValidate') easyValidate: string;
@Input('easyLabel') easyLabel;
private isRequired: boolean;
private patternName: string;
private master;
public easyConfig;
constructor(
public el: ElementRef
) {
this.easyConfig = errorConfiguration;
this.easyConfig['REQ'] = {'msg' : 'LABEL is mandatory'};
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
}
validate(control: AbstractControl): { [key: string]: any } {
let val = control.value;
let temp_arr = this.easyValidate.split('|');
this.isRequired = temp_arr[0] === 'REQ';
this.patternName = temp_arr.length > 0 ? temp_arr[1] : '';
if (this.isRequired) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (val == '' || val == null || val.toString().trim() == '') {
this.showErrorMsg('REQ');
return {
msoValidateRequired: false
};
}
}
if (this.patternName !== '' && ((val != '' && val != null))) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('keydown', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('change', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (this.getRegEx(this.patternName)) {
let pattern: RegExp = this.getRegEx(this.patternName);
if (pattern && !pattern.test(val) && val != '') {
this.showErrorMsg(this.patternName);
return {
msoValidatePattern: false
};
}
}
}
this.removeErrorMsgElement();
return null;
}
private showErrorMsg(msgKey: string) {
this.getErrorMsgElement().innerHTML = this.getErrorMsg(msgKey);
}
private getErrorMsgElement() {
let errorElementList = this.el.nativeElement.parentNode.getElementsByClassName('error-span');
return errorElementList.length ? errorElementList[0] : this.createErrorElement();
}
private createErrorElement() {
let errorSpan = document.createElement('span');
errorSpan.setAttribute('class', 'text-danger error-span hide');
return this.el.nativeElement.parentNode.appendChild(errorSpan);
}
private removeErrorMsgElement() {
this.getErrorMsgElement().remove();
}
private getErrorMsg(msgKey: string) {
let errMsg: string = this.getConfigMsg(msgKey) ? this.getConfigMsg(msgKey) : 'Invalid Value';
errMsg = errMsg.replace('LABEL', (this.easyLabel ? this.easyLabel : 'Field'));
return errMsg;
}
getRegEx(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['regex'];
}
return false;
}
getConfigMsg(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['msg'];
}
return false;
}
}
@NgModule({
declarations: [
AppComponent, .... , EasyValidatorDirective
],
imports: [ ... ],
bootstrap: [AppComponent]
})
export class AppModule { }
而所有的
脏活
都会进入控制消息
组件中。事实上,您可以利用一个专用组件来实现这一点。此组件将显示所有通用内容,如“标签”和错误区域。重要的一点是如何利用ng content
提供表单元素(input、textarea、select)作为该组件的输入
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
另一件有趣的事情是能够从组件引用与此输入相关联的控件。这样,您将能够透明地知道/显示与表单元素关联的验证错误
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
下面是此类组件的示例实现。首先,关联模板的内容:
<div class="form-group form-group-sm" [ngClass]="{'has-error':state && !state.valid}">
<label for="for"
class="col-sm-3 control-label”>{{label}}</label>
<div class="col-sm-8">
<ng-content ></ng-content>
<p *ngIf="state.pending">Fetching data from the server...</p>
<div *ngIf="state.dirty && !state.valid && !state.pending">
<p *ngIf="state.errors.required">Field is required.</p>
<p *ngIf="state.errors.startsWithNumber">Your field can't start with a number</p>
<p *ngIf="state.errors.usernameTaken">This field is taken</p>
</div>
</div>
</div>
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
然后,您可以在表单中以这种方式使用此组件:
<form [ngFormModel]="form">
<field label="Name">
<input type="text" [ngFormControl]="form.controls.username" />
</field>
<button (click)="submitData()" [disabled]="!form.valid" class="btn btn-primary">Sumbit data</button>
</form>
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
萨姆比特数据
有关更多详细信息,请参阅本文(“字段的表单组件”部分):
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
- 我希望现在回答这个问题已经太晚了,但这可能会帮助其他人。
为了克服这个问题,我创建了以下指令。该指令适用于模板驱动和反应式表单
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
它的作用:
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
准备配置文件
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
配置文件:错误配置。ts
export const errorConfiguration = {
'alphaNum': {
'regex': /^[a-zA-Z0-9 ]*$/,
'msg': 'LABEL should contain only alpaha numeric values'
},
'email': {
'regex': /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/,
'msg': 'LABEL is not valid email'
}
};
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
import { Directive, ElementRef, forwardRef, Input } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { errorConfiguration } from './error-configurations'; // use configuration file
@Directive({
selector: '[easyValidate]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EasyValidatorDirective), multi: true }
]
})
export class EasyValidatorDirective implements Validator {
@Input('easyValidate') easyValidate: string;
@Input('easyLabel') easyLabel;
private isRequired: boolean;
private patternName: string;
private master;
public easyConfig;
constructor(
public el: ElementRef
) {
this.easyConfig = errorConfiguration;
this.easyConfig['REQ'] = {'msg' : 'LABEL is mandatory'};
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
}
validate(control: AbstractControl): { [key: string]: any } {
let val = control.value;
let temp_arr = this.easyValidate.split('|');
this.isRequired = temp_arr[0] === 'REQ';
this.patternName = temp_arr.length > 0 ? temp_arr[1] : '';
if (this.isRequired) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (val == '' || val == null || val.toString().trim() == '') {
this.showErrorMsg('REQ');
return {
msoValidateRequired: false
};
}
}
if (this.patternName !== '' && ((val != '' && val != null))) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('keydown', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('change', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (this.getRegEx(this.patternName)) {
let pattern: RegExp = this.getRegEx(this.patternName);
if (pattern && !pattern.test(val) && val != '') {
this.showErrorMsg(this.patternName);
return {
msoValidatePattern: false
};
}
}
}
this.removeErrorMsgElement();
return null;
}
private showErrorMsg(msgKey: string) {
this.getErrorMsgElement().innerHTML = this.getErrorMsg(msgKey);
}
private getErrorMsgElement() {
let errorElementList = this.el.nativeElement.parentNode.getElementsByClassName('error-span');
return errorElementList.length ? errorElementList[0] : this.createErrorElement();
}
private createErrorElement() {
let errorSpan = document.createElement('span');
errorSpan.setAttribute('class', 'text-danger error-span hide');
return this.el.nativeElement.parentNode.appendChild(errorSpan);
}
private removeErrorMsgElement() {
this.getErrorMsgElement().remove();
}
private getErrorMsg(msgKey: string) {
let errMsg: string = this.getConfigMsg(msgKey) ? this.getConfigMsg(msgKey) : 'Invalid Value';
errMsg = errMsg.replace('LABEL', (this.easyLabel ? this.easyLabel : 'Field'));
return errMsg;
}
getRegEx(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['regex'];
}
return false;
}
getConfigMsg(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['msg'];
}
return false;
}
}
@NgModule({
declarations: [
AppComponent, .... , EasyValidatorDirective
],
imports: [ ... ],
bootstrap: [AppComponent]
})
export class AppModule { }
在配置文件中,指定正则表达式及其各自的错误消息。在错误消息中,如果指定了“easyLabel”属性,“LABEL”将替换为字段名
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
在您的元素中,需要按如下方式使用它:
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
案例1>强制电子邮件
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
案例2>非强制性电子邮件
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
案例3>规格字段标签,以获得更用户友好的错误消息
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
指令文件:easy validator.Directive.ts
export const errorConfiguration = {
'alphaNum': {
'regex': /^[a-zA-Z0-9 ]*$/,
'msg': 'LABEL should contain only alpaha numeric values'
},
'email': {
'regex': /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/,
'msg': 'LABEL is not valid email'
}
};
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
import { Directive, ElementRef, forwardRef, Input } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { errorConfiguration } from './error-configurations'; // use configuration file
@Directive({
selector: '[easyValidate]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EasyValidatorDirective), multi: true }
]
})
export class EasyValidatorDirective implements Validator {
@Input('easyValidate') easyValidate: string;
@Input('easyLabel') easyLabel;
private isRequired: boolean;
private patternName: string;
private master;
public easyConfig;
constructor(
public el: ElementRef
) {
this.easyConfig = errorConfiguration;
this.easyConfig['REQ'] = {'msg' : 'LABEL is mandatory'};
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
}
validate(control: AbstractControl): { [key: string]: any } {
let val = control.value;
let temp_arr = this.easyValidate.split('|');
this.isRequired = temp_arr[0] === 'REQ';
this.patternName = temp_arr.length > 0 ? temp_arr[1] : '';
if (this.isRequired) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (val == '' || val == null || val.toString().trim() == '') {
this.showErrorMsg('REQ');
return {
msoValidateRequired: false
};
}
}
if (this.patternName !== '' && ((val != '' && val != null))) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('keydown', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('change', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (this.getRegEx(this.patternName)) {
let pattern: RegExp = this.getRegEx(this.patternName);
if (pattern && !pattern.test(val) && val != '') {
this.showErrorMsg(this.patternName);
return {
msoValidatePattern: false
};
}
}
}
this.removeErrorMsgElement();
return null;
}
private showErrorMsg(msgKey: string) {
this.getErrorMsgElement().innerHTML = this.getErrorMsg(msgKey);
}
private getErrorMsgElement() {
let errorElementList = this.el.nativeElement.parentNode.getElementsByClassName('error-span');
return errorElementList.length ? errorElementList[0] : this.createErrorElement();
}
private createErrorElement() {
let errorSpan = document.createElement('span');
errorSpan.setAttribute('class', 'text-danger error-span hide');
return this.el.nativeElement.parentNode.appendChild(errorSpan);
}
private removeErrorMsgElement() {
this.getErrorMsgElement().remove();
}
private getErrorMsg(msgKey: string) {
let errMsg: string = this.getConfigMsg(msgKey) ? this.getConfigMsg(msgKey) : 'Invalid Value';
errMsg = errMsg.replace('LABEL', (this.easyLabel ? this.easyLabel : 'Field'));
return errMsg;
}
getRegEx(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['regex'];
}
return false;
}
getConfigMsg(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['msg'];
}
return false;
}
}
@NgModule({
declarations: [
AppComponent, .... , EasyValidatorDirective
],
imports: [ ... ],
bootstrap: [AppComponent]
})
export class AppModule { }
您需要在模块中声明此指令才能使用它
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
模块文件:app.Module.ts
export const errorConfiguration = {
'alphaNum': {
'regex': /^[a-zA-Z0-9 ]*$/,
'msg': 'LABEL should contain only alpaha numeric values'
},
'email': {
'regex': /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/,
'msg': 'LABEL is not valid email'
}
};
It will show following messages
If field is empty : Field is mandatory
If field is invalid email : Field is not valid demail ( this is from configuartion file LABEL is replaced with "Field" as easyLabel is not specified.)
import { Directive, ElementRef, forwardRef, Input } from '@angular/core';
import { Validator, AbstractControl, NG_VALIDATORS } from '@angular/forms';
import { errorConfiguration } from './error-configurations'; // use configuration file
@Directive({
selector: '[easyValidate]',
providers: [
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => EasyValidatorDirective), multi: true }
]
})
export class EasyValidatorDirective implements Validator {
@Input('easyValidate') easyValidate: string;
@Input('easyLabel') easyLabel;
private isRequired: boolean;
private patternName: string;
private master;
public easyConfig;
constructor(
public el: ElementRef
) {
this.easyConfig = errorConfiguration;
this.easyConfig['REQ'] = {'msg' : 'LABEL is mandatory'};
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
}
validate(control: AbstractControl): { [key: string]: any } {
let val = control.value;
let temp_arr = this.easyValidate.split('|');
this.isRequired = temp_arr[0] === 'REQ';
this.patternName = temp_arr.length > 0 ? temp_arr[1] : '';
if (this.isRequired) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (val == '' || val == null || val.toString().trim() == '') {
this.showErrorMsg('REQ');
return {
msoValidateRequired: false
};
}
}
if (this.patternName !== '' && ((val != '' && val != null))) {
this.el.nativeElement.addEventListener('blur', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('keydown', () => this.getErrorMsgElement().classList.remove('hide'), false);
this.el.nativeElement.addEventListener('change', () => this.getErrorMsgElement().classList.remove('hide'), false);
if (this.getRegEx(this.patternName)) {
let pattern: RegExp = this.getRegEx(this.patternName);
if (pattern && !pattern.test(val) && val != '') {
this.showErrorMsg(this.patternName);
return {
msoValidatePattern: false
};
}
}
}
this.removeErrorMsgElement();
return null;
}
private showErrorMsg(msgKey: string) {
this.getErrorMsgElement().innerHTML = this.getErrorMsg(msgKey);
}
private getErrorMsgElement() {
let errorElementList = this.el.nativeElement.parentNode.getElementsByClassName('error-span');
return errorElementList.length ? errorElementList[0] : this.createErrorElement();
}
private createErrorElement() {
let errorSpan = document.createElement('span');
errorSpan.setAttribute('class', 'text-danger error-span hide');
return this.el.nativeElement.parentNode.appendChild(errorSpan);
}
private removeErrorMsgElement() {
this.getErrorMsgElement().remove();
}
private getErrorMsg(msgKey: string) {
let errMsg: string = this.getConfigMsg(msgKey) ? this.getConfigMsg(msgKey) : 'Invalid Value';
errMsg = errMsg.replace('LABEL', (this.easyLabel ? this.easyLabel : 'Field'));
return errMsg;
}
getRegEx(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['regex'];
}
return false;
}
getConfigMsg(regKey: string) {
if (typeof this.easyConfig[regKey] !== 'undefined') {
return this.easyConfig[regKey]['msg'];
}
return false;
}
}
@NgModule({
declarations: [
AppComponent, .... , EasyValidatorDirective
],
imports: [ ... ],
bootstrap: [AppComponent]
})
export class AppModule { }
您可以创建自定义验证器或指令来生成所需的错误消息。我希望物质元素更加固执己见,并在默认情况下提供这样做的东西。我不知道jQuery,因此不清楚您到底想要什么。@GünterZöchbauer OP想要一个插件式的功能,您不必为每次验证编写
错误检查和html模板jquery.validate
执行该操作。因此,我认为她是在要求减少代码,我知道这个问题大体上是关于什么的,但它不是非常具体的理想解决方案应该是什么样子。通往罗马的道路有很多;-)写一个插件并把它加入到答案中,也许:-PHi伙计们,谢谢你们的支持。在我的帖子中,我必须为每个输入的一个错误定义一条消息。所以我在寻找一个好的解决方案,我会在输入字段中插入需要检查的错误,如果无效,错误消息将自动显示。这只是我的想法,我需要大家的建议。