Angular 5响应式表单:仅聚焦或加载无效数据时显示验证错误
我一眼就看到问题出在模板里的错误显示条件上!你当前的条件简化后其实就是只要控件无效就显示错误,这才导致空的未触碰输入框也会弹出错误提示。而minLength/maxLength看起来正常,是因为Angular内置的这两个验证器对空输入值会直接返回“无错误”,所以空输入时控件不会被标记为无效,自然不会显示错误。
第一步:修正模板中的错误显示条件
把你当前的条件替换成更精准的逻辑,同时给控件起别名简化代码:
<input [formControlName]="question.key" #ctrl="formControl"> <div *ngIf="ctrl.invalid && (ctrl.touched || ctrl.value !== '')" class="alert alert-danger"> <div *ngIf="ctrl.hasError('required')">Name is required.</div> <div *ngIf="ctrl.hasError('email')">Email Format is Incorrect.</div> <div *ngIf="ctrl.hasError('minlength')">Minimum Length Required.</div> <div *ngIf="ctrl.hasError('maxlength')">Maximum Length Required.</div> <div *ngIf="ctrl.hasError('postCode')">PostCode Incorrect.</div> </div>
这个条件的逻辑是:
- 只有当控件确实无效并且(用户已经触碰过控件,或者控件有初始值)时,才显示错误。
- 空的未触碰输入:
ctrl.value === ''且ctrl.touched === false,不满足条件,错误不显示; - 加载的无效数据(比如错误格式的邮箱):
ctrl.value !== ''且ctrl.invalid === true,满足条件,错误显示; - 用户触碰后:
ctrl.touched === true,只要控件无效就显示错误。
- 空的未触碰输入:
第二步:修复自定义邮编验证器
你的postCodeValidator没有处理空输入的情况,导致空输入时也会触发格式错误,这可能不符合预期。修改成下面这样,让它只在有输入值时才验证格式:
function postCodeValidator(control: FormControl) { const givenPostCode = control.value; // 空输入或纯空格,不触发格式验证 if (!givenPostCode || givenPostCode.trim() === '') { return null; } const UKPostCodePattern = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]))))\s?[0-9][A-Za-z]{2})$/; const isUKPostCodeValid = UKPostCodePattern.test(givenPostCode); if (!isUKPostCodeValid) { return { postCode: { required: "UK Valid PostCode", provided: givenPostCode } }; } return null; }
这样,如果邮编字段不是必填项,空输入不会显示错误;如果是必填项,由Validators.required来处理空输入的提示,职责更清晰。
为什么之前minLength/maxLength正常?
Angular内置的minLength和maxLength验证器会自动忽略空输入值(''、null、undefined),直接返回null(无错误),所以空输入时控件不会被标记为无效,自然不会触发错误显示。而required、email(当和required一起使用时)以及你的自定义邮编验证器,在空输入时会让控件变成无效状态,再加上你原来的错误条件有问题,就导致了错误提前显示。
内容的提问来源于stack exchange,提问作者K.Z
相关产品推荐
相关产品推荐

