如何在 Angular 5 应用程序中为 formGroup 配置多个验证
how to configure multiple validations for formGroup in Angular 5 application
我正在研究 Angular 反应式表单验证。我当前的结构只有 validation.required,我需要额外的验证来设置但很难做到。
我需要验证
- 最小长度,
- 电子邮件和
- 邮政编码
我正在根据 json 数据动态创建表单。
formGroup 验证服务
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
// need help here for forms.
});
return new FormGroup(group);
}
}
基本问题组件
export class QuestionBase<T>{
key: string;
label: string;
required: boolean;
minLength:number;
order: number;
controlType: string;
constructor(options: {
key?: string,
label?: string,
required?: boolean,
minLength?:number,
order?: number,
controlType?: string,
} = {}) {
this.key = options.key || '';
this.label = options.label || '';
this.required = !!options.required;
this.minLength = options.minLength;
this.order = options.order === undefined ? 1 : options.order;
this.controlType = options.controlType || '';
}
}
我还需要根据类型自定义验证错误,目前只有required!如以下代码
模板
<div [ngSwitch]="question.controlType">
<div *ngSwitchCase="'textbox'"> <small>textbox</small>
<div class="form-group">
<input *ngSwitchCase="'textbox'"
[formControlName]="question.key"
[id]="question.key"
[type]="question.type"
[(ngModel)]="question.value"
(keyup.enter)="onChangeValue($event, previousValue, responseId, question.key, 'textbox'); previousValue = question.value"
(blur)="onChangeValue($event, previousValue, responseId, question.key, 'textbox'); previousValue = question.value"
(focus)="previousValue=question.value"
>
<span></span>
</div>
</div>
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>
FormControl
接受单个验证器或验证器数组 (ValidatorFn | ValidatorFn[]
)。您可以将多个验证器作为数组传递。
class FormControl extends AbstractControl {
constructor(formState: any = null,
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null)
new FormControl(question.value || '', [Validators.required, Validators.minLength(5)])
这里 example code from angular docs 显示多条错误消息:
<input id="name" class="form-control"
formControlName="name" required >
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>
我就是这样修改的
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
var validations: ValidatorFn[] = [];
if(question.required) {
validations.push(Validators.required)
}
if(question.minLength)
{
validations.push(Validators.minLength(question.minLength))
}
group[question.key] = new FormControl(question.value || '', validations);
});
return new FormGroup(group);
}
}
将json数据映射到文本对象
if(questionElementType=="textbox")
{
let _textBox = new TextboxQuestion({
consultationId: questionsList[key].consultationId,
questionId: questionsList[key].questionId,
questionElementType: questionsList[key].questionElementType[0].title,
questionType: questionsList[key].questionType,
title:questionsList[key].title,
displayId: questionsList[key].displayId,
key: questionsList[key].questionId,
label: questionsList[key].title,
value: questionsList[key].answer.length<=0? null : questionsList[key].answer[0].answerValue,
required: true,
minLength:8,
order: 5
});
this.mappedQuestions.push(_textBox);
}
我正在研究 Angular 反应式表单验证。我当前的结构只有 validation.required,我需要额外的验证来设置但很难做到。 我需要验证 - 最小长度, - 电子邮件和 - 邮政编码
我正在根据 json 数据动态创建表单。
formGroup 验证服务
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
group[question.key] = question.required ? new FormControl(question.value || '', Validators.required)
: new FormControl(question.value || '');
// need help here for forms.
});
return new FormGroup(group);
}
}
基本问题组件
export class QuestionBase<T>{
key: string;
label: string;
required: boolean;
minLength:number;
order: number;
controlType: string;
constructor(options: {
key?: string,
label?: string,
required?: boolean,
minLength?:number,
order?: number,
controlType?: string,
} = {}) {
this.key = options.key || '';
this.label = options.label || '';
this.required = !!options.required;
this.minLength = options.minLength;
this.order = options.order === undefined ? 1 : options.order;
this.controlType = options.controlType || '';
}
}
我还需要根据类型自定义验证错误,目前只有required!如以下代码
模板
<div [ngSwitch]="question.controlType">
<div *ngSwitchCase="'textbox'"> <small>textbox</small>
<div class="form-group">
<input *ngSwitchCase="'textbox'"
[formControlName]="question.key"
[id]="question.key"
[type]="question.type"
[(ngModel)]="question.value"
(keyup.enter)="onChangeValue($event, previousValue, responseId, question.key, 'textbox'); previousValue = question.value"
(blur)="onChangeValue($event, previousValue, responseId, question.key, 'textbox'); previousValue = question.value"
(focus)="previousValue=question.value"
>
<span></span>
</div>
</div>
<div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
</div>
FormControl
接受单个验证器或验证器数组 (ValidatorFn | ValidatorFn[]
)。您可以将多个验证器作为数组传递。
class FormControl extends AbstractControl {
constructor(formState: any = null,
validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null,
asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null)
new FormControl(question.value || '', [Validators.required, Validators.minLength(5)])
这里 example code from angular docs 显示多条错误消息:
<input id="name" class="form-control"
formControlName="name" required >
<div *ngIf="name.invalid && (name.dirty || name.touched)"
class="alert alert-danger">
<div *ngIf="name.errors.required">
Name is required.
</div>
<div *ngIf="name.errors.minlength">
Name must be at least 4 characters long.
</div>
<div *ngIf="name.errors.forbiddenName">
Name cannot be Bob.
</div>
</div>
我就是这样修改的
@Injectable()
export class QuestionControlService {
constructor() { }
toFormGroup(questions: QuestionBase<any>[] ) {
let group: any = {};
questions.forEach(question => {
var validations: ValidatorFn[] = [];
if(question.required) {
validations.push(Validators.required)
}
if(question.minLength)
{
validations.push(Validators.minLength(question.minLength))
}
group[question.key] = new FormControl(question.value || '', validations);
});
return new FormGroup(group);
}
}
将json数据映射到文本对象
if(questionElementType=="textbox")
{
let _textBox = new TextboxQuestion({
consultationId: questionsList[key].consultationId,
questionId: questionsList[key].questionId,
questionElementType: questionsList[key].questionElementType[0].title,
questionType: questionsList[key].questionType,
title:questionsList[key].title,
displayId: questionsList[key].displayId,
key: questionsList[key].questionId,
label: questionsList[key].title,
value: questionsList[key].answer.length<=0? null : questionsList[key].answer[0].answerValue,
required: true,
minLength:8,
order: 5
});
this.mappedQuestions.push(_textBox);
}