angular - 依赖于其他表单控件的 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在验证器尝试验证时未定义(不在上下文中)。而且我不明白,因为我在验证器声明中绑定了该方法。
解决方案
您可以将控件定义为
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;
}
您可以按照本指南完成自己的验证
推荐阅读
- php - 如何使用codeigniter从一个表中移动多行并插入另一个表
- python - 如何通过组合 value_counts() 来制作数据框
- kubernetes - 使用 Kubeadm 部署的 CoreDNS 和 Ubuntu 18.04 集群的 Kubernetes DNS 解析问题
- ruby-on-rails - RAILS_ROOT/public 下的 Ruby on Rails 文件授权
- sql - SQLite:即使有索引,大型数据库中的查询也非常慢
- java - 无法在 Intellij IDEA 的 Spring Boot 中添加一个等于和哈希码的实体?
- sql - 当许多连续行的压力值相同时查找Machine_ID
- vim - Vim:如何检测命令中的范围类型?
- javascript - Javascript:export * from ... 使构建文件太重
- tkinter - 使用 tkinter 创建可变数量的检查按钮