我尝试使用Angular 2实现反应式表单,我在自定义验证器方面遇到了一些问题。
如果输入字段的值在输入字段的(minDate)和(maxDate)属性之间,我尝试使日期字段有效。如果未提供先前的值之一,则对最小和最大约束没有限制。
问题是当" start_date "字段已修改。 " start_date "触发了字段验证器(行为正常),但验证者是" end_date "尽管(maxDate)属性更改,但不会触发字段。我可以看到,因为" ngOnChanges "指令的方法被调用。
你知道我哪里错了吗?
非常感谢你的帮助。
这是我的代码:
组件:
this.task = this.formBuilder.group({
name: ['', Validators.required],
start_date: ['', Validators.required],
end_date: ['', Validators.required]
});
Vue的:
<form [formGroup]="task" (ngSubmit)="onSubmit()" novalidate>
<label for="name"><b>Name</b>: </label>
<input id="name" name="name" formControlName="name"/><br>
<label for="start_date"><b>Start</b>: </label>
<input id="start_date" name="start_date" formControlName="start_date"
[maxDate]="task.get('end_date').value"
appDateValidator/><br>
<label for="end_date"><b>End</b>: </label>
<input id="end_date" name="end_date" formControlName="end_date"
[minDate]="task.get('start_date').value"
appDateValidator/><br>
</form>
指令/校验器:
@Directive({
selector: '[appDateValidator]',
providers: [{ provide: NG_VALIDATORS, useExisting: DateValidatorDirective, multi: true }]
})
export class DateValidatorDirective implements Validator, OnChanges {
@Input() minDate: string;
@Input() maxDate: string;
private valFn = Validators.nullValidator;
constructor() { }
ngOnChanges(changes: SimpleChanges): void {
const minDateChange = changes['minDate'];
const maxDateChange = changes['maxDate'];
if (minDateChange) {
this.minDate = minDateChange.currentValue;
}
if (maxDateChange) {
this.maxDate = maxDateChange.currentValue;
}
this.valFn = DateValidator(this.minDate, this.maxDate);
}
validate(c: AbstractControl): ValidationErrors {
return this.valFn(c);
}
}
export function DateValidator(minDate: string, maxDate: string): ValidatorFn {
return (c: AbstractControl): { [key: string]: any } => {
let errors = null;
const dateValueMoment = moment.utc(c.value, moment.ISO_8601);
const minDateMoment = minDate ? moment.utc(minDate, moment.ISO_8601) : moment.invalid();
const maxDateMoment = maxDate ? moment.utc(maxDate, moment.ISO_8601) : moment.invalid();
if (!dateValueMoment.isValid()) {
errors = Object.assign({}, errors, {
'value': c.value
});
}
if (minDateMoment.isValid() && dateValueMoment.isBefore(minDate)) {
errors = Object.assign({}, errors, {
'min': minDate
});
}
if (maxDateMoment.isValid() && dateValueMoment.isAfter(maxDate)) {
errors = Object.assign({}, errors, {
'max': maxDate
});
}
return errors;
};
}