首页 > 解决方案 > 依赖于其他表单控件的 Angular formControl 验证器

问题描述

我需要创建一个包含 2 个日期、dateFrom 和 dateTo 的表单。 验证的条件是 dateFrom 不能在 dateTo 之后,并且 dateTo 不能在 dateFrom 之前。

所以我创建了一个表单组,其中包含两个表单控件和一个共同的验证器来检查这个条件。

export class DateRangeSelector {

    dateForm: FormGroup = new FormGroup({
         dateFrom: new FormControl({ year: 2017, month: 10 },[this.dateValidator.bind(this)]),
         dateTo: new FormControl({ year: 2020, month: 11 }, [this.dateValidator.bind(this)])
    });

dateValidator(control: FormControl): { [s: string]: boolean } {
    const valueDateFrom = this.dateForm.get('dateForm').value;
    const valueDateTo = this.dateForm.get('dateTo').value;
    if (valueDateFrom && valueDateTo) {
        //please ignore the fact that value is {year: x, month: y}, I need  to parse
        const dateFrom = moment(valueDateFrom);
        const dateTo = moment(valueDateTo);
        if (dateFrom.isAfter(dateTo)) {
            return { invalidDate: true };
        }
    }
    return null;
    }
}

我的问题是this.dateForm在验证器尝试验证时未定义(不在上下文中)。而且我不明白,因为我在验证器声明中绑定了该方法。

标签: angularvalidationangular-formsform-control

解决方案


您可以将控件定义为

new FormGroup({
        dateFrom: new FormControl('', [validateStartResult]),
        dateTo: new FormControl('', [validateEndResult]),
})

然后创建单独的文件进行验证

import {AbstractControl, ValidationErrors, ValidatorFn} from "@angular/forms";

enum ValidationFor {
    end = 'end',
    start = 'start'
}

export const validateEndResult: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
    return validateResult(control, ValidationFor.end);
}
export const validateStartResult: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
    return validateResult(control, ValidationFor.start);
}

function validateResult(control, currentValidation: ValidationFor): ValidationErrors | null {
    const startControl = control?.root?.get('dateFrom');
    const endControl = control?.root?.get('dateTo');

    const currentTime = new Date().getTime();
    const startTimeStamp = new Date(startControl?.value).getTime(); // configurations yours date
    const endTimeStamp = new Date(endControl?.value).getTime(); // configurations yours date

    const error: { [key: string]: boolean } = {};
    let hasError = false;

    if (startTimeStamp > endTimeStamp) { // main codition
        if (currentValidation === ValidationFor.end) {
            error.endResult = true
        }
        if (currentValidation === ValidationFor.start) {
            error.startResult = true
        }
        hasError = true;
    }

    return hasError ? error : null;
}

您可以按照本指南完成自己的验证


推荐阅读