我正在使用材料设计的 Angular 应用程序,并且正在使用 Moment.js 来解析和格式化日期。
在我的其中一页中,我有一个Material's Datepicker。我遵循了该材料的指导方针,使Datepicker与moment
对象配合使用-而不是对本机Date
对象配合使用。
我也设法以某种格式在日期选择器中显示日期。但是此格式在组件的提供程序中进行了硬编码。 如何根据用户偏好在运行时更改格式?
我已经安装了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
答案 0 :(得分:3)
好的,所以我终于找到了一种在运行时更改mat-date-picker
格式的方法(文档完全没有帮助)。
您可能已经有这样的服务,如果没有,则应该创建一个服务,以便可以将日期格式控制在一个位置。
// 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
}
}
// 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
中进行一些改动。
// 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 { /* ... */ }
P.S
请注意,问题中的代码(来自“ demo.component.ts”)不再相关。
答案 1 :(得分:1)
感谢您的想法!只是为了澄清。您可以使用非单一服务来设置日期选择器值的自定义格式。扩展代码:
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;
}
答案 2 :(得分:0)
更新:如果用户希望手动输入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);
}