带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker

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

这个问题在这里已经有了答案:





Custom Component MdDatePicker used in reactive Form

(1 个回答)


1年前关闭。




我正在尝试将 ControlValueAccessor 与 Angular Material datepicker 一起使用。出于某种原因,它不适用于 formControlName 和响应式(Reactive)表单。有人可以解决这个问题吗?正在为某些样式和属性构建包装器。值被发送到 react 形式等

https://material.angular.io/components/datepicker/overview

typescript :

import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'app-date-picker',
  templateUrl: './date-picker.component.html',
  styleUrls: ['./date-picker.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DatePickerComponent),
      multi: true
    }
  ], host: {
    '(change)': 'onChange($event)',
    '(blur)': 'onTouch()'
  }
})

export class DatePickerComponent implements OnInit {
  @Input() Value: Date = new Date();
  @Input() PlaceHolder: string;
  @Input() Label:string;
  @Output() dateValueAction = new EventEmitter();

  onChange: any = () => { };
  onTouch: any = () => { };
  constructor() { }

  ngOnInit() {
  }

  set valueUpdated(val) {
    this.Value = val;
    this.onChange(val);
    this.onTouch(val);
  }

  writeValue(obj: any): void {
    this.Value = obj;
    this.valueUpdated = obj;
  }
  registerOnChange(fn: any): void {
    this.onChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.onTouch = fn;
  }

  dateValueChanged() {
    this.valueUpdated = this.Value;
    this.dateValueAction.emit(this.Value);
  }
}

HTML:
<mat-form-field appearance="outline">
    <mat-label>{{Label}}</mat-label>   
    <input matInput [matDatepicker]="picker" placeholder={{PlaceHolder}} [(value)]="Value" (dateChange)="dateValueChanged()">
    <mat-datepicker-toggle matSuffix [for]="picker">
        <mat-icon matDatepickerToggleIcon>calendar_today</mat-icon>
    </mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

想用formControlName等实现
<app-date-picker formControlName="startDate">

最佳答案

实现 ControlValueAccessor您不应该使用标准的输入/输出通信机制。输入值由 writeValue 提供,通知控件的变化形式(输出值)是通过调用registerOnChange提供的回调函数来完成的.

请尝试以下代码:

export class DatePickerComponent implements ControlValueAccessor {
  private value: Date = new Date();
  @Input() placeHolder: string;
  @Input() label: string;

  private onChange: Function;
  private onTouch: Function;

  writeValue(obj: Date): void {
    this.value = obj;
  }
  registerOnChange(fn: Function): void {
  this.onChange = fn;
  }
  registerOnTouched(fn: Function): void {
    this.onTouch = fn;
  }
  dateValueChanged(): void {
    this.onChange(this.value)
  }
}

另一点是您直接在组件装饰器描述符中指定了类。
这样做你不应该使用 forwardRef .

 providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: DatePickerComponent,
      multi: true
    }
  ]

关于带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59097915/

相关文章:

Angular Material Typography 设置不正确

javascript - 着陆页需要时间来加载/显示

Angular 2 帖子 : Not sending 'content-type: application/json' to server

javascript - Angular react 形式 *ngFor 循环,无法读取未定义的 'property'

TypeScript Generic Factory Function Type,匹配数组元素顺序

angular - 错误 : @angular/material/material has no exported member 'MdButtonModule'

angular - 如何从 Material Angular 使用分页器?

angular - 轻量级图表 : How can i add chart which look like this way?

javascript - Angular2 - 我怎么知道在 Angular2 应用程序中选择了哪个单选按钮

javascript - 转换匿名函数参数