angular - 如何將控制封裝到自訂 ControlValueAccessor 並遵守驗證規則
我有一個 matDatePicker,我在整個應用程式中使用反應式表單,如下所示:
<mat-form-field>
<input formControlName="ratingDate" matInput [matDatepicker]="picker1"
placeholder="Rating Date" (dateInput)="performnCustomValidation)">
<mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
<mat-datepicker #picker1></mat-datepicker>
</mat-form-field>
然而,有一個驗證錯誤,我需要通過一些額外的事件處理來解決:
performnCustomValidation(event: MatDatepickerInputEvent<Date>) {
var strValue = (event.targetElement as HTMLInputElement).value
if (event.value === null && strValue) {
this.dateFormControl.setErrors({ isDate: true }, { emitEvent: true});
}
}
所以我決定把這個包裝成自訂控制項。
我該如何讓驗證在我的自訂包裝元件中像以前一樣運作?
那意味著它必須尊重
- 內建 matDatePicker 驗證
- FormControl 驗證器
- 我的自訂驗證錯誤
- 驗證狀態必須以與之前相同的視覺效果呈現
到目前為止我有這個,但沒有驗證
@Component({
selector: 'app-date-picker',
template: `
<mat-form-field class="large-input" floatLabel="always">
<input #input1 matInput [matDatepicker]="picker1" (dateChange)="performCustomValidation($event)">
<mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
<mat-datepicker #picker1></mat-datepicker>
</mat-form-field>`,
styleUrls: ['./date-picker.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent),
multi: true
}
]
})
export class DatePickerComponent implements ControlValueAccessor, AfterViewInit {
@ViewChild(MatInput) matInput;
@ViewChild('input1') input;
private control: FormControl;
onChange: any = (date: Date) => { };
onTouched: any = () => { };
constructor(private injector: Injector,
) {
}
// The form control is only set after initialization
ngAfterViewInit(): void {
const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) {
this.control = ngControl.control as FormControl;
} else {
}
}
performnCustomValidation(event: MatDatepickerInputEvent<Date>) {
var strValue = (event.targetElement as HTMLInputElement).value
if (event.value === null && strValue) {
this.dateFormControl.setErrors({ isDate: true }, { emitEvent: true});
}
}
writeValue(value) {
this.matInput.value = value;
}
registerOnChange(fn) {
this.onChange = fn;
}
// We implement this method to keep a reference to the onTouched
//callback function passed by the forms API
registerOnTouched(fn) {
this.onTouched = fn;
}
}