我正在为我的组件实现 ControlValueAccessor,并且我在表单中有许多可以更改的日期范围。
我创建了一个自定义验证器,用于检查日期范围之间的任何重叠:
test.component.html
<ng-container *ngIf="value as v">
<form rangeValidator [ranges]="v.ranges" #dateForm="ngForm" >
<div *ngFor="let x of v.ranges;let index = index;trackBy:trackIndex;">
<input type="date" [(ngModel)]="x.start" #start='ngModel' name="start-{{index}}">
<input type="date" [(ngModel)]="x.end" #end='ngModel' name="end-{{index}}">
<button (click)="removeRange(index)">
<mat-icon>delete</mat-icon>
</button>
</div>
</form>
</ng-container>
测试组件.ts
@ViewChild('dateForm') dateForm;
@Output('onValidChange') onValidChange: EventEmitter<boolean | Boolean> = new EventEmitter<boolean | Boolean>();
writeValue(obj): void {
this.value = obj;
}
onChange = (_) => { };
onTouched = () => { };
registerOnChange(fn: (_: any) => void): void { this.onChange = fn; }
registerOnTouched(fn: () => void): void { this.onTouched = fn; }
private _value= {};
public get value(){
if (this.dateForm!== undefined){
this.dateForm.valueChanges.subscribe(values => {
this.onValidChange.next(this.dateForm.valid);
// this is emitting validity to the parent component, which then disables the submit button based on it.
})
}
return this._value;
}
public set value(v) {
this._value = v;
this.onChange(v);
}
dateRange.validator.directive.ts
import { NG_VALIDATORS, Validator, AbstractControl } from '@angular/forms';
import { Directive, Input } from '@angular/core';
@Directive({
selector: '[rangeValidator]',
providers: [
{
provide: NG_VALIDATORS,
useExisting: RangeValidator,
multi: true
}
]
})
export class RangeValidator implements Validator {
@Input() ranges;
public constructor() {}
validate(formGroup): { } | null {
//code to perform overlapping logic
if (overlapped) {
return {
overlapping: true
}
} else {
return null;
}
}
}
}
验证逻辑工作正常,但有效性是根据之前的表单值反映的。例如,如果我输入了重叠的值,表格保持有效,然后我删除了重叠,表格将变为无效。即使验证器正在接收最新的值。知道为什么它不能立即反映正确的有效性吗?