带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker [英] Angular Material Datepicker with ControlValueAccessor and formControlName

查看:27
本文介绍了带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

打字稿:

import { Component, OnInit, Input, Output, EventEmitter, forwardRef } from '@angular/core';从@angular/forms"导入{NG_VALUE_ACCESSOR};@成分({选择器:'应用程序日期选择器',templateUrl: './date-picker.component.html',styleUrls: ['./date-picker.component.scss'],供应商: [{提供:NG_VALUE_ACCESSOR,useExisting: forwardRef(() => DatePickerComponent),多:真}], 主持人: {'(change)': 'onChange($event)','(模糊)':'onTouch()'}})导出类 DatePickerComponent 实现 OnInit {@Input() 值:Date = new Date();@Input() 占位符:字符串;@Input() 标签:字符串;@Output() dateValueAction = new EventEmitter();onChange: any = () =>{ };onTouch: any = () =>{ };构造函数(){}ngOnInit() {}设置值更新(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;}日期值更改(){this.valueUpdated = this.Value;this.dateValueAction.emit(this.Value);}}

HTML:

想用formControlName等实现

解决方案

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

请尝试以下代码:

导出类 DatePickerComponent 实现 ControlValueAccessor {私有值:Date = new Date();@Input() placeHolder: 字符串;@Input() 标签:字符串;私有 onChange:函数;私人 onTouch:功能;写值(对象:日期):无效{this.value = obj;}registerOnChange(fn: 函数): void {this.onChange = fn;}registerOnTouched(fn: 函数): void {this.onTouch = fn;}dateValueChanged(): void {this.onChange(this.value)}}

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

 提供者:[{提供:NG_VALUE_ACCESSOR,使用现有:DatePickerComponent,多:真}]

I am trying to utilize ControlValueAccessor with Angular Material datepicker. For some reason, its not not working with formControlName and a reactive form. Can someone resolve this? The wrappers are being built for certain styling and attributes. The values are sent to reactive form, etc

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>

Wanting to implement with formControlName, etc

<app-date-picker formControlName="startDate">

解决方案

Implementing ControlValueAccessor you shouldn't use the standard input/output communication mechanism.
The input value is provided by writeValue, notifying the form of changes in the control (output value) is done by calling the callback function provided by registerOnChange.

Please try the following code:

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)
  }
}

Another point is you specified the class directly in component decorator descriptor. doing so you shouldn't be using forwardRef.

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

这篇关于带有 ControlValueAccessor 和 formControlName 的 Angular Material Datepicker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆