如何在Angular 5应用中为FormGroup配置多规则表单验证
没问题,我帮你一步步把这些验证规则和自定义错误提示加进去,咱们从基础类开始改起:
第一步:扩展基础问题类,支持邮箱/邮编验证标识
首先得给QuestionBase类添加标记字段,用来区分哪些输入需要邮箱或邮编验证,同时保留已有的minLength属性:
export class QuestionBase<T>{ key: string; label: string; required: boolean; minLength: number; order: number; controlType: string; // 新增邮箱、邮编验证标识 isEmail: boolean; isZipCode: boolean; constructor(options: { key?: string, label?: string, required?: boolean, minLength?: number, order?: number, controlType?: string, isEmail?: boolean, isZipCode?: boolean } = {}) { 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 || ''; this.isEmail = !!options.isEmail; this.isZipCode = !!options.isZipCode; } }
第二步:更新表单控制服务,添加所有验证规则
接下来修改QuestionControlService,把需要的验证器(包括自定义邮编验证)都整合进去,替换原来单一的Validators.required:
import { Injectable } from '@angular/core'; import { FormControl, FormGroup, Validators, ValidatorFn, AbstractControl } from '@angular/forms'; import { QuestionBase } from './question-base'; // 自定义邮编验证器(以中国6位数字邮编为例,可根据需求修改正则) function zipCodeValidator(): ValidatorFn { return (control: AbstractControl): { [key: string]: any } | null => { const valid = /^\d{6}$/.test(control.value); return valid ? null : { zipCode: { value: control.value } }; }; } @Injectable() export class QuestionControlService { constructor() { } toFormGroup(questions: QuestionBase<any>[] ) { const group: any = {}; questions.forEach(question => { // 收集当前字段需要的所有验证器 const validators: ValidatorFn[] = []; if (question.required) { validators.push(Validators.required); } if (question.minLength) { validators.push(Validators.minLength(question.minLength)); } if (question.isEmail) { validators.push(Validators.email); } if (question.isZipCode) { validators.push(zipCodeValidator()); } // 创建FormControl并传入验证器数组 group[question.key] = new FormControl(question.value || '', validators); }); return new FormGroup(group); } }
第三步:修改模板,显示对应错误提示
最后更新模板,根据不同的错误类型显示自定义提示(注意要确保模板能访问到表单实例,比如通过@Input() form: FormGroup;传入):
<div [ngSwitch]="question.controlType"> <div *ngSwitchCase="'textbox'"> <small>textbox</small> <div class="form-group"> <input [formControlName]="question.key" [id]="question.key" <!-- 邮箱类型自动设置input为email类型 --> [type]="question.isEmail ? 'email' : 'text'" [(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="form.get(question.key).invalid && form.get(question.key).touched"> <span *ngIf="form.get(question.key).errors?.['required']">{{question.label}} is required</span> <span *ngIf="form.get(question.key).errors?.['minlength']"> {{question.label}} must be at least {{question.minLength}} characters long </span> <span *ngIf="form.get(question.key).errors?.['email']"> {{question.label}} must be a valid email address </span> <span *ngIf="form.get(question.key).errors?.['zipCode']"> {{question.label}} must be a valid 6-digit zip code </span> </div> </div>
示例动态表单数据
现在你可以这样定义JSON数据来生成带验证的表单字段:
const formQuestions: QuestionBase<any>[] = [ new QuestionBase({ key: 'username', label: 'Username', required: true, minLength: 5, controlType: 'textbox' }), new QuestionBase({ key: 'userEmail', label: 'Email', required: true, isEmail: true, controlType: 'textbox' }), new QuestionBase({ key: 'userZip', label: 'Zip Code', required: true, isZipCode: true, controlType: 'textbox' }) ];
这样改完之后,你的动态表单就能支持必填、最小长度、邮箱格式和邮编格式的验证,每个错误类型都会显示对应的自定义提示。如果需要适配其他国家的邮编规则,只修改zipCodeValidator里的正则表达式就行。
内容的提问来源于stack exchange,提问作者K.Z
相关产品推荐
相关产品推荐

