I have a custom directive validator that uses an input to check validity. Using the original value, the validity works just fine. If I update the input, though, the validator still says the error and does not re-evaluate the value. How can I force a re-evaluation upon an update to the input?
directive:
export class TimeRangeValidatorDirective implements Validator {
@Input() maxTime;
@Input() minTime;
validate(control: AbstractControl): ValidationErrors | null {
return CustomValidators.timeRange(this.maxTime, this.minTime)(control);
}
}
When min or max time update, I would like to cause the validation to re-run so that if the new max is above the control value or the new min is below it, previous errors will not persist
EDIT Based on the answer given by @Kevin Zhang (re-writing it here for clarity)
The solution:
export class TimeRangeValidatorDirective implements Validator {
private _onChange?: ()=>void;
private _maxTime;
private _minTime;
@Input()
get maxTime() { return this._maxTime}
set maxTime(value) {
this._maxTime = value;
if(this._onChange) {
this._onChange();
}
}
@Input()
get minTime() { return this._minTime}
set minTime(value) {
this._minTime = value;
if(this._onChange) {
this._onChange();
}
}
validate(control: AbstractControl): ValidationErrors | null {
return CustomValidators.timeRange(this.maxTime, this.minTime)(control);
}
registerOnValidatorChanges(fn:()=>void): void {
this._onChange = fn;
}
}
Please refer to below code use getter/setter and register validator change fn.
@Directive({
selector:
':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
providers: [REQUIRED_VALIDATOR],
host: {'[attr.required]': 'required ? "" : null'}
})
export class RequiredValidator implements Validator {
private _required = false;
private _onChange?: () => void;
/**
* @description
* Tracks changes to the required attribute bound to this directive.
*/
@Input()
get required(): boolean|string {
return this._required;
}
set required(value: boolean|string) {
this._required = value != null && value !== false && `${value}` !== 'false';
if (this._onChange) this._onChange();
}
/**
* @description
* Method that validates whether the control is empty.
* Returns the validation result if enabled, otherwise null.
*/
validate(control: AbstractControl): ValidationErrors|null {
return this.required ? Validators.required(control) : null;
}
/**
* @description
* Registers a callback function to call when the validator inputs change.
*
* @param fn The callback function
*/
registerOnValidatorChange(fn: () => void): void {
this._onChange = fn;
}
}