如何在没有 moment.js 依赖的情况下格式化 Angular Material datepicker

Posted

技术标签:

【中文标题】如何在没有 moment.js 依赖的情况下格式化 Angular Material datepicker【英文标题】:How can I format the Angular Material datepicker without moment.js dependency 【发布时间】:2021-04-11 08:01:39 【问题描述】:

我想实现什么?

我希望我的 Angular Material(v11) 日期选择器在 Angular 版本 11 项目中使用 DD-MM-YYYY 格式。

我尝试了什么?

我尝试使用 MatMomentDateModule 但这使用了 moment.js 库。这反过来将使用包中的所有语言环境,从而将包大小增加 400kb。我已将CUSTOM_DATE_FORMATS 添加到我的app.module.ts 的提供者中,如下所示:

const CUSTOM_DATE_FORMATS = 
    parse: 
        dateInput: 'DD-MM-YYYY',
    ,
    display: 
        dateInput: 'DD-MM-YYYY',
        monthYearLabel: 'MMMM YYYY',
        dateA11yLabel: 'LL',
        monthYearA11yLabel: 'MMMM YYYY',
    ,
;

这可行,但如前所述,捆绑包大小严重增加,我不使用任何语言环境。

有没有办法在不使用 moment.js 库的情况下格式化我的日期 DD-MM-YYYY?

moment.js 是否可以通过某种方式进行 treeshak,以便我只使用我需要的东西?

【问题讨论】:

如果我没记错的话 NativeDateModule 使用相同的注入令牌,即 MAT_DATE_FORMATS。因此,您应该能够在不使用 MomentDateAdapter 的情况下为此添加自定义提供程序。虽然不确定解析 - 我会尝试在空闲时间设置闪电战并检查。 哦,真的吗?我认为那是 moment.js 特定的。一定会很感激闪电战! 我的立场是正确的 - 一定是使用 MomentDateAdapter 的方式太多了。 github.com/angular/components/blob/master/src/material/core/… 它只使用 MAT_DATE_LOCALE,所以肮脏的出路是在组件内提供语言环境并收工。其他肮脏的选择是扩展 NativeDateAdapter 并覆盖格式/解析方法,以便它不使用语言环境,而是使用您定义的格式。最好的解决方案是编写自定义 DateAdapter 并改用它。抱歉,也许有人想出了更好的解决方案。 【参考方案1】:

所以我不知道您是否使用了MatNativeDateModule,您还可以实现自定义日期适配器。我认为这是 MatMomentDateModule 特有的东西。

一旦我发现这一点,我就可以覆盖格式化函数并手动格式化它:

export class CustomDateAdapter extends NativeDateAdapter 
    format(date: Date, displayFormat: any): string 
        const days = date.getDate();
        const months = date.getMonth() + 1;
        const year = date.getFullYear();
        return days + '-' + months + '-' + year;
    

并像这样实现它:

@NgModule(

  providers: [
    
      provide: DateAdapter,
      useClass: AppDateAdapter,
      deps: [MAT_DATE_LOCALE, Platform]
    ,
  ]

)
export class AppModule  

【讨论】:

嘿 Martijn,很好的解决方案,没有瞬间依赖!您知道将这种方法应用于单个 Datepicker 的方法吗?我正在尝试构建仅月/年的日期选择器,并且需要相应地格式化输入。 @SamScholefield 仅在使用日期选择器的组件中使用此提供程序。如果您在此特定组件中有更多日期选择器,只需创建仅包含该日期选择器的新组件 太好了,谢谢。但我建议选择 ISO8601 格式以获得更好的全球兼容性,(如果它可能在全球范围内使用):return $year-$months-$days;【参考方案2】:

我自己今天也遇到了同样的问题,不想使用 moment.js。 如果您只想要标准日期格式(例如非美国),一个简单的解决方案似乎是添加到您的 app.module.ts

import  MAT_DATE_LOCALE  from '@angular/material/core';
@NgModule(
...
  providers: [provide: MAT_DATE_LOCALE, useValue: 'en-GB'],
...

毫无疑问,其他国家/地区代码也可以使用。这种方法可能会更改您的应用程序(不仅仅是您的日期选择器)中的所有日期外观,但在我的情况下这是完全可以接受的。无需对组件和 html 模板进行进一步更改。

【讨论】:

以上是关于如何在没有 moment.js 依赖的情况下格式化 Angular Material datepicker的主要内容,如果未能解决你的问题,请参考以下文章

使用moment.js解析时如何忽略时区

如何使用 moment.js 将此值 theHour[0].times 更改为时间格式 (HH:mm)

moment.js的方法总结

moment.js的常用方法

如何在 Vue 模板内的 Moment.js 格式化程序上转义 HTML 字符串?

Node.js怎么处理数据库中日期类型