【问题标题】:How to change output format of material 2 date-picker如何更改材料 2 日期选择器的输出格式
【发布时间】:2017-11-13 10:43:15
【问题描述】:

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

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

例如。 “2017-11-13T10:39:28.300Z”

但我想用语言环境日期值修补我的表单控件

例如。 “2017 年 11 月 13 日,下午 4:09:46”

以便它输出后来的格式,甚至期望这种格式。

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

一些想法:

我应该写 customDateAdaptor 吗?

更新:

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

我尝试通过扩展 nativeDateAdaptor 来实现自定义 dateAdaptor

【问题讨论】:

    标签: angular datepicker momentjs angular-material2


    【解决方案1】:

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

    更新:

    这是 Moutaz-homsi 转载的使用这种方法的参考实现

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

    【讨论】:

    • 来自@Ankit Raonka 的好东西。这很好用。
    • 抱歉,当您从输入中键入日期时它不起作用,日期选择器起作用但您的输入不起作用。
    • 我也有类似的问题,由于这个答案有输入问题,我又在stackoverflow.com/q/66072525/4321097问了一遍
    【解决方案2】:

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

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

    更多详情见第二条评论:https://github.com/angular/material2/issues/5722

    编辑:

    我找不到格式化输出的方法,因此我将材料日期选择器组件包装到自定义组件中。

    这个自定义组件在属性上有 2 种方式绑定来获取日期: @Input() selectedValue@Output() selectedValueChange: EventEmitter<any> = new EventEmitter<any>();

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

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

    onChange 函数获取日期选择器值_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;
      }
    }
    

    【讨论】:

    • 我确实做到了,但格式只是为了以您的格式显示值,我希望表单的输出采用非 iso 格式。 this.myform.value 在 iso 字符串中给我日期
    • 我找不到这样做的方法,所以我将日期选择器包装到自定义组件中。请参阅上面的编辑答案
    【解决方案3】:

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

    截至今天,Angular Material Date Module 支持两种提供日期值的方式MatNativeDateModuleMatMomentDateModuleMatNativeDateModule 默认接受 ISO 8601 格式。但是由于您不想使用ISO 格式,我建议使用MatMomentDateModule(Moment.js 实现)。

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

    【讨论】:

      【解决方案4】:

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

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

      NativeDateAdapter 使用Intl API 来格式化输出日期。您可以尝试提供一个自定义的 MAT_NATIVE_DATE_FORMATS 实例,但我不确定这可以让您走多远。

      编辑

      您当前使用的是 2.0.0-beta12 的 angular/material,它不适合您基于 5.0.0-rc0/master 的代码。代码库有一些变化,尤其是 2.0.0-beta12 中不存在的反序列化函数,这就是它没有被调用的原因。如果您无法更新到 angular 5,请查看 MatDatepickerInput.setValue/coerceDateProperty,它将日期设置为您的 FormControl

      【讨论】:

      • 我想用这个日期选择器让我们说生日。输出采用 UTC 格式,因此出生日期将根据您的服务器所在位置而变化。输出不应该是时区感知的,因为生日不能改变。知道怎么做吗?
      • @AnkitRaonka 看到我的编辑,我相信这是你当前的问题
      【解决方案5】:

      您可以调用该模块的Emitter(例如点击事件)并将绑定到该模块的模型更改为辅助模型。

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

          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;
            }
          

          【讨论】:

            【解决方案8】:

            你可以像这样改变它的格式:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2019-02-24
              • 1970-01-01
              • 2018-08-25
              • 2021-02-22
              • 1970-01-01
              • 2019-03-04
              • 2019-06-02
              相关资源
              最近更新 更多