如何在遵守验证的情况下将控件包装到自定义ControlValueAccessor

时间:2019-04-16 09:24:42

标签: angular typescript angular-material angular-reactive-forms

我有一个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});
  }
}

所以我决定将其包装到自定义控件中。

如何像以前一样在自定义包装器组件中进行验证?

这意味着它必须尊重

  1. 内置的matDatePicker验证
  2. FormControl验证器
  3. 我的自定义验证错误
  4. 验证状态必须以与以前相同的视觉方式反映

到目前为止,我有这个,但是没有验证

@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;
  }
}

0 个答案:

没有答案