【问题标题】:Angular Date Picker - Update MAT_DATE_FORMATS dynamicallyAngular Date Picker - 动态更新 MAT_DATE_FORMATS
【发布时间】:2026-01-01 17:05:01
【问题描述】:

我正在开发一个可以处理日期的 Angular9 应用程序。 它显示和更新几个<mat-datepicker> 字段。

我正在使用来自https://www.npmjs.com/package/@angular/material-moment-adapter 的自定义MAT_DATE_FORMATSMomentDateAdapter (@angular/material-moment-adapter)。

我正在使用以下代码,它可以正常工作:

export const APP_MOMENT_DATE_FORMATS =
{    
  parse: {},
  display: {
    dateInput: 'YYYY/MM/DD/MM',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM YYYY'
  }
};

//..
providers: [
  {
     provide: MAT_DATE_FORMATS, useValue: APP_MOMENT_DATE_FORMATS
  },
  {
    provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]
  }
]
// ..

Stackblitz 演示:https://stackblitz.com/edit/angular-formatted-datepicker-vdtaqj?file=app%2Fdatepicker-overview-example.ts

现在,我想知道是否可以动态地更新APP_MOMENT_DATE_FORMATS.display.dateInput 的值 - 例如:可能会通过 http 请求从配置服务中设置 ,或者我会在界面中显示一个选择器

示例:

export const APP_MOMENT_DATE_FORMATS =
  {  
    // ..  
    display: {
     dateInput: this.appService.dateInputFormat,
     // ..
   }
  };

我知道我可以实现自定义日期适配器,如下所述:Angular 2 Material 2 datepicker date format

但我想知道是否有另一种方法可以做到这一点,而无需实现新的自定义日期适配器。

谢谢。

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    在花费数小时寻找解决方案后,我通过简单地注入 MAT_DATE_FORMATS 并动态更改它来提出以下解决方案:

    const APP_MOMENT_DATE_FORMATS =
    {
        parse: {
        dateInput: 'MM/DD/YYYY',
        },
        display: {
        dateInput: 'MM/DD/YYYY',
        monthYearLabel: 'MMM YYYY',
        dateA11yLabel: 'LL',
        monthYearA11yLabel: 'MMMM YYYY'
        }
    };
    
    @Component({
    ...  
    providers: [
        {
        provide: MAT_DATE_FORMATS, useValue: APP_MOMENT_DATE_FORMATS
        },
        {
        provide: DateAdapter,
        useClass: MomentDateAdapter,
        deps: [MAT_DATE_LOCALE]
        }
    ]
    })
    
    export class DatePickerComponent implements OnInit, OnDestroy {
    
    constructor(@Inject(MAT_DATE_FORMATS) public data: any) {
        data.parse.dateInput = 'DD/MM/YYYY'
        data.display.dateInput = 'DD/MM/YYYY'
      }
    }
    

    【讨论】:

    • 如何在 DatePickerComponent 类中动态改变内部方法?
    【解决方案2】:

    不太清楚如何在运行时更新提供程序的值,但有一种解决方法可以在组件级别为mat-datepicker 提供不同的MAT_DATE_FORMATS 值。

    Angular Docs中所述:

    同一元素上的组件和指令共享一个注入器。

    将具有不同MAT_DATE_FORMATS 提供程序的customPickerFormats 指令放入包装mat-datepickermat-form-field

    在directice.ts中:

    import { Directive } from '@angular/core';
    import { MAT_DATE_FORMATS } from '@angular/material/core';
    
    @Directive({
      selector: '[appCustomPickerFormats]',
      providers: [
        {
          provide: MAT_DATE_FORMATS,
          useValue: {
            parse: {
              dateInput: 'DD/MM',
            },
            display: {
              dateInput: 'Do MMMM',
              monthYearLabel: 'MMM',
              dateA11yLabel: 'LL',
              monthYearA11yLabel: 'MMMM YYYY',
            },
          },
        },
      ],
    })
    export class CustomPickerFormatsDirective {}
    
    

    在component.ts中:

    <mat-form-field appCustomPickerFormats>
      <mat-label>Choose a date</mat-label>
      <input matInput [matDatepicker]="customPicker">
      <mat-datepicker-toggle matSuffix [for]="customPicker"></mat-datepicker-toggle>
      <mat-datepicker #customPicker></mat-datepicker>
    </mat-form-field>
    

    默认情况下,第一个不带指令的mat-datepicker 将使用您为 HostComponent 或组件放置的模块设置的任何 MAT_DATE_FORMATS 值。

    一个有效的 stackblitz 示例here

    【讨论】: