繁体   English   中英

如何在运行时更改 Angular Material Datepicker 格式

[英]How to change Angular Material Datepicker format in run-time

我正在使用Material Design 开发一个Angular应用程序,我正在使用Moment.js来解析和格式化日期。

在我的其中一个页面中,我有一个Material 的 Datepicker 我遵循了材料的指导方针,使 Datepicker 与moment对象一起工作 - 而不是在本机Date对象上。

我还设法以某种格式在 Datepicker 中显示日期。 但是这种格式在组件的提供者中是硬编码的。 如何根据用户偏好在运行时更改格式?

这是我到目前为止所拥有的:

我已经安装了 npm 的软件包:

$ npm i moment -S
$ npm i @angular/material-moment-adapter -S
// app.module.ts
import { MatMomentDateModule } from '@angular/material-moment-adapter'
...
@NgModule({
  imports: [
    MatMomentDateModule,
...
// demo.component.ts
import * as moment from 'moment';
import { MAT_DATE_FORMATS } from '@angular/material/core';
const MY_FORMATS = {
  parse: {
    dateInput: 'LL',
  },
  display: {
    dateInput: 'LL',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM YYYY',
  },
};
@Component({
  selector: 'app-demo',
  templateUrl: './demo.component.html',
  styleUrls: ['./demo.component.scss'],
  providers: [
    { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
  ],
})
export class DemoComponent {
   public dateVal = moment();
}
// demo.component.html
<mat-form-field>
  <input matInput [matDatepicker]="myDatePicker" [(ngModel)]="dateVal">
  <mat-datepicker-toggle matSuffix [for]="myDatePicker"></mat-datepicker-toggle>
  <mat-datepicker #myDatePicker></mat-datepicker>
</mat-form-field>

如您所见,日期格式是在组件的提供程序中定义的。 如何在运行时更改此设置?

可以在此处找到一个工作示例:
https://stackblitz.com/angular/mgaargebgpd?file=app%2Fdatepicker-formats-example.ts

好的,所以我终于找到了一种在运行时更改mat-date-picker格式的方法(文档根本没有帮助)。

步骤 #1 - 创建一个将提供格式的服务。

您可能已经拥有这样的服务,如果没有,您应该创建一个,这样您就可以在一个地方控制日期格式。

// date-time.service
import { Injectable } from '@angular/core';
import * as moment from 'moment';

@Injectable({ providedIn: 'root' })
export class DateTimeService
{
  public getFormat(): string
  {
    return "DD-MM-YYYY"; // add you own logic here
  }
  public getLocale(): string
  {
    return "he-IL"; // add you own logic here
  }  
}

步骤 #2 - 创建一个CustomDateAdapter ,它将负责在运行时解析日期

// customDateAdapter.ts
import { Injectable } from '@angular/core';
import { MomentDateAdapter } from '@angular/material-moment-adapter';
import * as moment from 'moment';
import { DateTimeService } from './date-time.service';

@Injectable()
export class CustomDateAdapter extends MomentDateAdapter
{
  constructor(private _dateTimeService: DateTimeService)
  {
    super('en-US'); // set default locale
  }

  public format(date: moment.Moment, displayFormat: string): string
  {
    const locale = this._dateTimeService.getLocale();
    const format = this._dateTimeService.getFormat();

    return date.locale(locale).format(format);
  }
}

请注意:“ CustomDateAdapter ”是一个常规类,而不是一个组件。 虽然我们正在这个类注入一个服务。 为此,我们需要将@Injectable()装饰器添加到“CustomDateAdapter”,并在app.module.ts进行一些轻微的更改。

第 3 步 - 修改 app.module.ts 以支持自定义格式并允许对 CustomDateAdapter 进行依赖注入。

// app.module.ts
import { DateAdapter, MatNativeDateModule } from '@angular/material';
import { MatMomentDateModule } from '@angular/material-moment-adapter'
import { CustomDateAdapter } from './<some-path>/customDateAdapter';

@NgModule({
  imports:
  [
    MatNativeDateModule,
    MatMomentDateModule
  ],
  providers:
  [
    CustomDateAdapter, // so we could inject services to 'CustomDateAdapter'
    { provide: DateAdapter, useClass: CustomDateAdapter }, // Parse MatDatePicker Format
  ]
})
export class AppModule { /* ... */ }

聚苯乙烯
请注意,问题中的代码(来自“demo.component.ts”)不再相关。

Stackblitz 上的演示

谢谢你的想法! 只是为了澄清。 您可以使用非单例服务来设置日期选择器值的自定义格式。 扩展你的代码:

import { Injectable } from '@angular/core';
    @Injectable({ providedIn: 'root' })
    export class DateTimeService {
        private _format = 'DD.MM.YYYY';

        set format(value: string) {
            this._format = value;
        }

        public getFormat(): string {
            return this._format;
        }

        public getLocale(): string {
            return 'ru-ru';
        }
    }

如果你像这样注入这个服务:

providers: [
        { provide: MAT_DATE_LOCALE, useValue: 'ru-ru' },
        CustomDateAdapter,
        DateTimeService,
        { provide: DateAdapter, useClass: CustomDateAdapter, deps: [DateTimeService] }
]

您可以在组件工作期间存储组件中的任何值。

constructor(private dateTimeService: DateTimeService) {
    }

    ngOnInit() {
        this.dateTimeService.format = this.format;
    }

更新:如果用户想要手动输入 DateTime 而不是从 DateTime 选择器中选择 DateTime(删除输入 DateTime 上的只读属性),@Gil Epshtain 的解决方案不起作用。 我对customDateAdapter.ts更新:

public parse(value: any, parseFormat: string | string[]): moment.Moment | null {
if(!value) {
  return null
}
const format = this._dateTimeService.getFormat();
return _moment(value, format, false);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM