带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker [重复]

Posted

技术标签:

【中文标题】带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker [重复]【英文标题】:Angular Material Datepicker with ControlValueAccessor and formControlName [duplicate] 【发布时间】:2020-03-24 15:29:34 【问题描述】:

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

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

打字稿:

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">

【问题讨论】:

【参考方案1】:

在实现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
    
  ]

【讨论】:

谢谢,这也是 Angular Material ***.com/questions/47885568/… 的旧语法,如果需要,请随时在此处发布您的答案

以上是关于带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker [重复]的主要内容,如果未能解决你的问题,请参考以下文章

带有表单组的子 ControlValueAccessor 组件 - 检查后表达式已更改

Angular 材质中具有错误验证的 ControlValueAccessor

实现 ControlValueAccessor 和 Validator 的 MatFormFieldControl 创建循环依赖

为啥在 Angular 中实现 ControlValueAccessor 时需要在 writeValue 中调用 onChange 和 onTouch?

ChangeDetectionStrategy.OnPush 打破了 ControlValueAccessor 的禁用状态

Angular 7 - ControlValueAccessor - 修剪绑定到表单的输入值