我希望validate form
中有angular2
。我学习了一些文档,它将被定义为:
<form [ngFormModel]="form">
<input type="text" ngControl="username" />
<p *ngIf="username.pending">Fetching data from the server...</p>
<div *ngIf="username.dirty && !username.valid && !username.pending">
<p *ngIf="username.errors.required">Username is required.</p>
<p *ngIf="username.errors.startsWithNumber">Your username can't start with a number</p>
<p *ngIf="username.errors.usernameTaken">This username is taken</p>
</div>
<button (click)="submitData()" [disabled]="!form.valid" class="btn btn-primary">Sumbit data</button>
</form>
constructor(private builder: FormBuilder) {
this.username = new Control(
"",
Validators.compose([Validators.required, UsernameValidator.startsWithNumber]),
UsernameValidator.usernameTaken
);
this.form = builder.group({
username: this.username
});
}
对于每个输入,我需要定义许多错误消息。我觉得这不好
我想要像jquery.validate,我只是定义input
并且错误消息将自动呈现,就像这样
<input required name="username" maxlength='8' pattern="^(?!\s|.*\s$).*$" ...>
答案 0 :(得分:3)
要减少代码,一种方法可能是编写组件。
将处理所有condition checkings
和error messages
This guy did a nice job here of implementing and explaining it.
HTML with Component看起来像这样
<input ngControl="email" id="email" />
<control-messages control="email"></control-messages>
并且所有dirty work
都会进入control-messages
组件。
答案 1 :(得分:0)
事实上,您可以利用专用组件来实现这一目标。该组件将包含所有通用内容,例如&#34; label&#34;和错误区域。重要的一点是利用ng-content
提供表单元素(input,textarea,select)作为此组件的输入的方法。
另一个有趣的事情是能够从组件引用与此输入关联的控件。这样,您将能够透明地知道/显示与表单元素关联的验证错误。
以下是此类组件的示例实现。首先是相关模板的内容:
<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>
和组件本身
@Component({
selector: 'field',
templateUrl: 'field.html'
})
export class FormFieldComponent {
@Input()
label: string;
@Input()
feedback: boolean;
@ContentChild(NgFormControl) state;
(...)
}
然后您可以在表单中使用此组件:
<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>
有关更多详细信息,请参阅此文章(部分&#34;字段&#34的表单组件;)
答案 2 :(得分:0)
我希望现在回答这个问题的时间要晚,但这可能对其他人有所帮助。 为了解决这个问题,我创建了以下指令。该指令适用于模板驱动和&amp;反应形式。
它的作用:
使用方法:
准备配置文件。
配置文件:error-configurations.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'
}
};
在配置文件中,指定正则表达式及其各自的错误消息。在错误消息中,如果指定了“easyLabel”属性,则“LABEL”将替换为字段名称。
在你的元素中需要按如下方式使用它:
案例1&gt;强制性电子邮件
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&gt;非必填电子邮件
It will show following message
If field is invalid email : Field is not valid demail
案例3&gt;特殊字段标签,用于更友好的错误消息
It will show following messages
If field is empty : Email Address is mandatory
If field is in valid email : Email Address is not valid email
指令文件:easy-validator.directive.ts
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;
}
}
您需要在模块中声明此指令才能使用它。
模块文件:app.module.ts
@NgModule({
declarations: [
AppComponent, .... , EasyValidatorDirective
],
imports: [ ... ],
bootstrap: [AppComponent]
})
export class AppModule { }