【问题标题】:Angular mat-datepicker with date mask带日期掩码的角 mat-datepicker
【发布时间】:2018-06-23 19:55:06
【问题描述】:

我使用 mat-datepicker 在 Angular5 中编写自定义日期选择器输入组件 imments ControlValueAccessor

date-picker.component.html:

<mat-form-field>
    <input matInput [matDatepicker]="picker" [(ngModel)]="value" (blur)="onBlur()">
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker (selectedChanged)="onChange($event)" #picker></mat-datepicker>
</mat-form-field>

date-picker.component.ts :

import { Component, OnInit, Input, Output, forwardRef, EventEmitter } from '@angular/core';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
import { MAT_MOMENT_DATE_FORMATS, MomentDateAdapter } from '@angular/material-moment-adapter';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

const noop = () => {
};

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => DatePickerComponent),
  multi: true
};

@Component({
  selector: 'app-date-picker',
  templateUrl: './date-picker.component.html',
  styleUrls: ['./date-picker.component.css'],
  providers: [
    { provide: MAT_DATE_LOCALE, useValue: 'he-IL' },
    { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
    { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
    CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR
  ],
})
export class DatePickerComponent implements OnInit, ControlValueAccessor {

  @Input()
  required: boolean;

  @Output()
  change: EventEmitter<Date> = new EventEmitter<Date>();

  innerValue: Date = new Date();

  //Placeholders for the callbacks which are later provided
  //by the Control Value Accessor
  private onTouchedCallback: () => void = noop;
  private onChangeCallback: (_: any) => void = noop;


  //get accessor
  get value(): Date {
    return this.innerValue;
  };

  //set accessor including call the onchange callback
  set value(v: Date) {
    if (v !== this.innerValue) {
      this.innerValue = v;
    }
  }

  constructor(private adapter: DateAdapter<any>) { }

  ngOnInit() {
    this.adapter.setLocale('he');
  }

  //Occured value changed from module
  writeValue(value: any): void {
    if (value !== this.innerValue) {
      this.innerValue = value;

      //invoke value change event
      this.change.emit(this.innerValue);
    }
  }
  registerOnChange(fn: any): void {
    this.onChangeCallback = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouchedCallback = fn;
  }

  onChange(event) {
    this.value = event;
    this.onBlur();
  }

  onBlur() {
    this.onChangeCallback(this.innerValue);
    //invoke value change event
    this.change.emit(new Date(this.innerValue));
    //this.onTouchedCallback();
  }
}

我想添加执行日期掩码的功能,例如 'dd/MM/yyyy'

我找到了匹配的示例,但它是用 angularJS 和 md datepicker 编写的:

Angular Material Datepicker and ngMask

有在 Angular 中实现的想法吗?

编辑:

附加现场演示,基于 Vivek Doshi 不错的答案,由于 [textMask] 属性,此演示无法正常工作。

Live Demo

【问题讨论】:

  • 当你说你想强制执行时,你的意思是你想强制用户只写一个有效的日期,还是你只想把日期识别为dd/MM/YYYY
  • 我的意思是强制使用有效格式来帮助用户编写正确的日期。 (我会在提交前检查值,但我不希望用户可以写任何文本)
  • 好吧,如果你真的想强制,你可以禁用输入,只启用点击日历按钮,这样用户只能在日历中选择他的日期
  • 这是个好主意,但是如果用户想设置远日期它不友好,还有一些用户更喜欢键盘而不是鼠标。
  • 我同意。也许你可以take a look at this example

标签: angular datepicker angular-material


【解决方案1】:

您可以在 angular2-text-mask

的帮助下实现这一目标

组件端:

public mask = {
    guide: true,
    showMask : true,
    mask: [/\d/, /\d/, '/', /\d/, /\d/, '/',/\d/, /\d/,/\d/, /\d/]
  };

模板端:

<mat-form-field>
  <input matInput [textMask]="mask" [matDatepicker]="picker" placeholder="Choose a date">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

WORKING DEMO

现在你需要做的就是绑定逻辑和验证,

这里是WORKING DEMOControlValueAccessor的解决方案。


第三个演示,使用您的代码

WORKING DEMO

【讨论】:

  • 谢谢!,它的优秀和正确的解决方案,但是,在我们的项目中,我们创建了一个自定义日期组件实现 ControlValueAccessor,并且 angular2-text-mask 报告了一个限制(来自 NPM):“不幸的是,我们目前无法支持 Ionic 2 离子输入,因为它覆盖了 Text Mask 执行其工作所需的 ControlValueAccessor。”,也许你有解决这个问题的想法?
  • @StackOverflow,请阅读这个,github.com/text-mask/text-mask/issues/668,如果你不把ion-input放在ion-item里面,它会起作用。
  • 看不懂你的解决方案,我修改了问题并添加了我的组件代码,如果你能再次关注我会很高兴!
  • @VivekDoshi 我怎样才能使它适应反应形式?
【解决方案2】:

如果我理解了你的问题,你为什么不试试pipe?像这样:

"{{yourDateModel | date: 'dd/MM/yyyy'}}"

在你的 html date-picker 组件中

【讨论】:

  • 这个日期管道只处理日期显示。我想强制执行日期输入掩码
猜你喜欢
  • 2021-03-07
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 2020-02-09
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2018-12-24
相关资源
最近更新 更多