3

对于学期的两个关联时间,一个开始时间,一个结束时间,理论上开始时间是不能大于结束时间的,所以在前台进行表单提交时,需要对其进行验证,保证数据正确性.

angular验证器

我使用的是响应式表单,首先的学习怎么添加验证器,简单去官网总结了一下:

1.每个控件在进行赋值时,都会过一遍所有的验证器,所有的控制器都通过的话就会进行赋值.
2.若有一个验证器不通过,都不会进行赋值,同时在errors属性中会添加上未通过的验证失败属性
3.我们可以通过验证失败的属性来提示用户

在angular官网上找到了一串实例代码:
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
  return (control: AbstractControl): {[key: string]: any} | null => {
    const forbidden = nameRe.test(control.value);
    return forbidden ? {'forbiddenName': {value: control.value}} : null;
  };
}

执行forbiddenNameValidator()方法,会返回一个ValidatorFn类型的方法,此方法接收了一个AbstractControl的对象,并要求返回null或{[key: string]: any},这么说来,我们只需要提供一个方法,根据提供的控件获取值,在方法中进行判断,根据逻辑返回null(即通过验证)或返回一个对象(属性名即为验证错误的名字,值随意填写).

实现方法

因为无论时开始时间或结束时间变化,都需要触发验证,并且验证错误类型还需要同步,尝试了几番,最终的解决方案是在开始时间控件和结束时间控件中都添加一个验证器:

this.validateForm.get('startTime').setValidators(this.semesterService.validatorSemester(this.validateForm));
this.validateForm.get('endTime').setValidators(this.semesterService.validatorSemester(this.validateForm));

无论是开始时间改变或者是结束时间改变,都会同时触发验证器,验证函数如下,当两个控件值不符合我们预期时,就往第三方控件timeError中添加错误属性'time',若通过验证就删除错误是属性.

validatorSemester(validateForm: FormGroup): ValidatorFn {
        return (some: AbstractControl): { [key: string]: any } | null => {
            if (!this.judgeSemesterTime(validateForm)) {
                validateForm.get('timeError').setErrors({ 'time': {} });
            } else {
                validateForm.get('timeError').setErrors(null);
            }
            return null;
        };
    }

前台在根据错误属性提供提醒:

<nz-form-explain
            *ngIf=" validateForm.get('timeError').errors?.time" style="color:red;">
                结束时间必须在开始时间之后!
            </nz-form-explain>

clipboard.png

待完善

当时写得比较匆忙,想到什么就写什么了,虽然实现了功能,但是代码却不能够复用,验证代码与空间名紧紧的耦合在了一起,并且还多写了一个多余的控件仅仅用来显示错误信息。
打算写通用的验证方法,接受两个控件对象,一个比较方法(类似compereTo接口),错误信息提示(就是之前返回的错误类型{['key':any]}),把所有的添加验证错误逻辑写到验证方法中,只需要调用者提供比较方法和错误信息(便于前台判断),这样就可以实现通用验证了.


鲸冬香
456 声望27 粉丝