问题描述
我正在尝试将 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!