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

Gil*_*ain 5 datepicker momentjs angular-material angular

我正在使用Material Design开发Angular应用,并且正在使用Moment.js解析和格式化日期。

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

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

这是我到目前为止的内容:

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

$ npm i moment -S
$ npm i @angular/material-moment-adapter -S
Run Code Online (Sandbox Code Playgroud)
// app.module.ts
import { MatMomentDateModule } from '@angular/material-moment-adapter'
...
@NgModule({
  imports: [
    MatMomentDateModule,
...
Run Code Online (Sandbox Code Playgroud)
// 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();
}
Run Code Online (Sandbox Code Playgroud)
// 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>
Run Code Online (Sandbox Code Playgroud)

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

一个有效的示例可以在这里找到:https :
//stackblitz.com/angular/mgaargebgpd?file=app%2Fdatepicker-formats-example.ts

Gil*_*ain 7

好的,所以我终于找到了一种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
  }  
}
Run Code Online (Sandbox Code Playgroud)

步骤#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);
  }
}
Run Code Online (Sandbox Code Playgroud)

请注意:“ 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 { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

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

更新:

由于很多人的要求,我在Stackblitz进行了演示。
演示
(请注意,由于所有代码都在一个视图/页面中,因此您需要重新打开选择器以查看格式更改。在实际应用中,您可能会拥有一个设置/配置页面,用于定义格式,因此您不会遇到此问题。)

  • 您可以创建一个stackblitz演示吗? (3认同)
  • 如果我在2个不同的页面中需要两种不同的格式,则将无法使用。 (2认同)