如何更改材料2日期选择器的输出格式

时间:2017-11-13 10:43:16

标签: angular datepicker momentjs angular-material2

我正在使用角度材质2 Date-Picker组件

它理解的唯一字符串输入是ISO日期格式

实施例。 " 2017-11-13T10:39:28.300Z"

但我想修改带有区域设置日期值

的表单控件

实施例。 " 11/13 / 2017,4:09:46 PM"

因此它输出后面的格式,甚至需要这种格式。

我该怎么做?有没有办法不使用ISO而是使用自定义格式?

一些想法:

我应该写customDateAdaptor吗?

更新

https://stackblitz.com/edit/angular-material-moment-adapter-example-bqvm2f

我试图通过扩展nativeDateAdaptor

来实现自定义dateAdaptor

8 个答案:

答案 0 :(得分:6)

最好的解决方案是使用ControlValueAccessor并创建一个自定义输入组件,这将使您可以控制组件的输入和输出。

更新

以下是使用Moutaz-homsi再现的这种方法的参考实现

https://stackblitz.com/edit/angular-dlxnmx?file=app%2Fcva-date.component.ts

答案 1 :(得分:4)

你需要创建一个扩展NativeDateAdapter的类(来自“@ angular / material / core”)

如果覆盖格式化功能,您将在选择日期后更改输入上日期的显示方式。 手动编辑输入值时,将调用解析函数,以显示有效日期。

有关详情,请参阅第2条评论:https://github.com/angular/material2/issues/5722

修改

我找不到格式化输出的方法,所以我将材质的datepicker组件包装到自定义组件中。

此自定义组件在属性上具有双向绑定以获取日期: @Input() selectedValue@Output() selectedValueChange: EventEmitter<any> = new EventEmitter<any>();

在ngInit上设置private _selectedValue;,它将包含日期选择日期。

然后在模板中,html datepicker输入元素具有[(ngModel)]="_selectedValue" (dateChange)="onChange($event)"

onChange函数获取datepicker值_selectedValue,对其进行格式化并将其发送到selectedValueChange

最终组件如下所示:

import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
import {
  DateAdapter,
  NativeDateAdapter,
  MAT_DATE_FORMATS,
  MAT_DATE_LOCALE
} from "@angular/material/core";
import * as moment from "moment";

const CUSTOM_DATE_FORMATS = {
  parse: {
    dateInput: { month: "short", year: "numeric", day: "numeric" }
  },
  display: {
    dateInput: "input",
    monthYearLabel: { year: "numeric", month: "short" },
    dateA11yLabel: { year: "numeric", month: "long", day: "numeric" },
    monthYearA11yLabel: { year: "numeric", month: "long" }
  }
};
const dateFormat = "YYYY-MM-DD";
// date adapter formatting material2 datepickers label when a date is selected
class AppDateAdapter extends NativeDateAdapter {
  format(date: Date, displayFormat: Object): string {
    if (displayFormat === "input") {
      return moment(date).format(dateFormat);
    } else {
      return date.toDateString();
    }
  }
}
@Component({
  selector: "datepicker",
  templateUrl: "./datepicker.component.html",
  styleUrls: ["./datepicker.component.scss"],
  providers: [
    { provide: MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },
    { provide: DateAdapter, useClass: AppDateAdapter }
  ]
})
export class DatepickerComponent implements OnInit {
  @Input() placeholder;
  @Output() onFilter: EventEmitter<any> = new EventEmitter<any>();
  @Input() selectedValue;
  @Output() selectedValueChange: EventEmitter<any> = new EventEmitter<any>();

  private _selectedValue;
  constructor() {}

  ngOnInit() {
    this._selectedValue = this.selectedValue;
  }

  onChange($event) {
    this.selectedValue = this.updateDate($event.value);
    this.onFilter.emit(this.selectedValue);
  }

  updateDate(date) {
    let formatedDate;
    if (date !== undefined) {
      formatedDate = moment(date).format(dateFormat);
    }
    this.selectedValueChange.emit(formatedDate);
    return formatedDate;
  }
}

答案 2 :(得分:3)

不确定,如果您已经这样做了,但我发现了一些可能让您对实施有所了解的信息。

截至今天,from PIL import Image tupledlist=[(71, 146, 110), (71, 146, 98), (71, 146, 99), (71, 146, 109), (71, 146, 26), (71, 146, 99), (71, 146, 109), (71, 146, 26), (71, 146, 91), (71, 146, 26), (71, 146, 110), (71, 146, 95), (71, 146, 109), (71, 146, 110), (71, 146, 26), (71, 146, 103), (71, 146, 95), (71, 146, 109), (71, 146, 109), (71, 146, 91), (71, 146, 97), (71, 146, 95), (71, 146, 26), (71, 146, 91), (71, 146, 104), (71, 146, 94), (71, 146, 26), (71, 146, 110), (71, 146, 98), (71, 146, 99), (71, 146, 109), (71, 146, 26), (71, 146, 99), (71, 146, 109), (71, 146, 26), (71, 146, 91), (71, 146, 26), (71, 146, 110), (71, 146, 95), (71, 146, 109), (71, 146, 110), (71, 146, 26), (71, 146, 102), (71, 146, 99), (71, 146, 109), (71, 146, 110)] OUTPUT_IMAGE_SIZE = (1280, 720) image = Image.new('RGB', OUTPUT_IMAGE_SIZE) image.putdata(tupledlist) image.save("path.png") print("Saved image.") image=Image.open("path.png") print(list(image.getdata())) 支持两种提供日期值<a download href="https://blabla-bucket.s3.amazonaws.com/imaginefolder/testfilename.csv?AWSAccessKeyId=111&Expires=222&Signature=333">Download</a> Angular Material Date Module的方法。默认情况下,MatNativeDateModule接受MatMomentDateModule格式。但由于您不想使用MatNativeDateModule格式,我建议使用ISO 8601(Moment.js实现)。

当我们使用ISO时,日期对象不再是JavaScript MatMomentDateModule对象,而是MatMomentDateModule(利用Moment js实例可用的方法,如{{1} }})。使用Moment.js在Material Date Picker docs页面上提供了基本到中间的示例。此外,一旦您的日期是Moment.js实例,您可以覆盖MomentDateAdapter而不是本机日期适配器的方法(格式,解析。)。

答案 3 :(得分:1)

您可能需要编写一个全新的适配器或使用时刻适配器。 @angular/material-moment-adapter:5.0.0-rc0。适配器使用momentjs,允许您更多地控制输出格式。

Moment也能够解析不同的输入格式。

NativeDateAdapter使用Intl API格式化输出日期。您可以尝试提供自定义的MAT_NATIVE_DATE_FORMATS实例,但我不确定这会给您带来多大的帮助。

修改

您目前正在使用角度/材质的2.0.0-beta12,这与基于5.0.0-rc0 / master的代码不相符。代码库有变化,特别是2.0.0-beta12中没有的反序列化函数,这就是为什么它没有被调用。如果您无法更新为角度5,请查看MatDatepickerInput.setValue/coerceDateProperty,将日期设置为FormControl

答案 4 :(得分:0)

您可以调用此模块的发射器(例如,单击事件)并将绑定到此模块的模型更改为辅助模型。

答案 5 :(得分:0)

首次导入并设置格式。 https://momentjs.com/

 import * as moment from 'moment';

setDateFormat(date) {
    this.myDate = moment(date).format('YYYY/MM/DD HH:mm:ss');
  }

答案 6 :(得分:0)

我有一个非常简单的解决方案。

  1. 使用自定义日期适配器
// create date.helpers.ts

import { formatDate } from '@angular/common';
import { Injectable } from '@angular/core';
import { NativeDateAdapter } from '@angular/material/core';

export const PICK_FORMATS = {
    parse: { dateInput: { month: 'short', year: 'numeric', day: 'numeric' } },
    display: {
        dateInput: 'input',
        monthYearLabel: { year: 'numeric', month: 'short' },
        dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
        monthYearA11yLabel: { year: 'numeric', month: 'long' }
    }
};

@Injectable({
    providedIn: 'root'
})
export class PickDateAdapter extends NativeDateAdapter {
    format(date: Date, displayFormat: Object): string {
        if (displayFormat === 'input') {
            return formatDate(date, 'dd/MM/yyyy', this.locale);;
        } else {
            return date.toDateString();
        }
    }
}

将此添加到

// your.module.ts

 providers: [
    NomineeService,
    { provide: MAT_FORM_FIELD_DEFAULT_OPTIONS, useValue: { appearance: 'legacy' } },
    { provide: DateAdapter, useClass: PickDateAdapter },
    { provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS },
  ]

  1. 自定义Javascript日期函数,将ISODate转换为可读的字符串
//shared.service.ts
formatDate(date): string {
    const _date = new Date(date);
    const day = _date.getDate();
    const month = _date.getMonth() + 1;
    const year = _date.getFullYear();
    return `${year}-${month}-${day}`;
  }

  formatTime(date: Date): string {
    const _date = new Date(date);
    const hours = _date.getHours()
    const minutes = _date.getMinutes();
    const seconds = _date.getSeconds();
    return `${hours}:${minutes}:${seconds}`;
  }

  toDateTimestamp(date: Date): string {
    const dateStamp = this.formatDate(date);
    const timeStamp = this.formatTime(date);
    return `${dateStamp} ${timeStamp}`
  }
  calculateDays(fromDate, toDate): number {
    const FromDate = new Date(fromDate);
    const ToDate = new Date(toDate);
    const difference = ToDate.getTime() - FromDate.getTime();
    const days = Math.round((difference / (1000 * 60 * 60 * 24)));
    return days;
  }

答案 7 :(得分:-1)

你可以改变它的格式:

 const Date = Date.replace(/-/g, '/')