web-dev-qa-db-fra.com

Comment changer le format de sortie du matériau 2 date-picker

J'utilise un matériau angulaire 2 Date-Picker composant

La seule entrée de chaîne qu'il comprend est au format de date ISO

Ex. "2017-11-13T10: 39: 28.300Z"

Mais je veux patcher mon contrôle de formulaire avec la valeur de date locale 

Ex. "13/11/2017, 16:09:46"

Alors qu'il sort le dernier format et attend même ce format.

Comment puis-je faire ceci? Existe-t-il un moyen de ne pas utiliser les formats ISO mais personnalisés?

Quelques idées:

Devrais-je écrire customDateAdaptor?

Mettre à jour:

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

j'ai essayé d'implémenter dateAdaptor personnalisé en étendant nativeDateAdaptor

2
Ankit Raonka

La meilleure solution consiste à utiliser ControlValueAccessor et à créer un composant d’entrée personnalisé, ce qui vous permettra de contrôler l’entrée et la sortie du composant.

mettre à jour:

Voici l'implémentation de référence utilisant cette approche reproduite par Moutaz-homsi 

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

6
Ankit Raonka

Vous devez créer une classe qui étend NativeDateAdapter (à partir de "@ angular/material/core")

Si vous remplacez la fonction de formatage, vous modifierez la manière dont la date est affichée sur l'entrée après la sélection d'une date. La fonction d'analyse est appelée lorsque vous modifiez manuellement la valeur d'entrée pour afficher une date valide.

Voir le 2e commentaire pour plus de détails: https://github.com/angular/material2/issues/5722

EDIT:

Je ne pouvais pas trouver un moyen de formater la sortie, j'ai donc intégré le composant matériau datepicker à un composant personnalisé.

Ce composant personnalisé a une liaison bidirectionnelle sur une propriété pour obtenir la date: @Input() selectedValue et @Output() selectedValueChange: EventEmitter<any> = new EventEmitter<any>();

Un private _selectedValue; est défini sur ngInit, il contiendra la date datepicker.

Ensuite, dans le modèle, l'élément d'entrée html datepicker a [(ngModel)]="_selectedValue" (dateChange)="onChange($event)"

La fonction onChange récupère la valeur datepicker _selectedValue, la formate et l’émet à selectedValueChange.

Le dernier composant ressemble à ceci:

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

Pas sûr, si vous le faites déjà, mais j'ai trouvé des informations qui pourraient vous donner une idée de votre mise en œuvre. 

À partir d’aujourd’hui, le Angular Material Date Module prend en charge deux méthodes permettant de fournir une valeur de date MatNativeDateModule et MatMomentDateModule. La MatNativeDateModule accepte le format ISO 8601 par défaut. Mais comme vous ne voulez pas utiliser le format ISO, je suggérerais d'utiliser MatMomentDateModule (implémentation Moment.js). 

Lorsque nous utilisons la variable MatMomentDateModule, l'objet de date n'est plus un objet JavaScript Date, mais plutôt un Moment.js instance (profitez des méthodes disponibles pour une instance js de Moment telle que format()). Des exemples basiques à intermédiaires sont disponibles sur la page de documentation de Matériau Sélecteur de date utilisant le fichier Moment.js. De plus, une fois que votre date est une instance de Moment.js, vous pouvez écraser les méthodes (format, analyse.) De MomentDateAdapter au lieu de l’adaptateur de date natif.

3
mrsan22

Vous devrez probablement écrire un tout nouvel adaptateur ou utiliser l’adaptateur Moment. @angular/material-moment-adapter:5.0.0-rc0. L’adaptateur de moment utilise momentjs et vous permet de contrôler beaucoup plus le format de sortie.

Moment est également capable d'analyser différents formats d'entrée.

NativeDateAdapter utilise Intl API pour formater la date de sortie. Vous pouvez essayer de fournir une instance personnalisée MAT_NATIVE_DATE_FORMATS mais je ne suis pas sûr de savoir à quoi cela vous mènera.

EDIT

Vous utilisez actuellement la version 2.0.0-beta12 d'angles/matériaux qui ne correspond pas à votre code basé sur la version 5.0.0-rc0/master. Il y a des changements dans la base de code, en particulier la fonction de désérialisation qui n'est pas présente dans 2.0.0-beta12, c'est pourquoi elle n'est pas appelée. Si vous ne pouvez pas effectuer la mise à jour vers l'angle 5, examinez MatDatepickerInput.setValue/coerceDateProperty qui définit la date dans votre FormControl.

1
kuhnroyal

vous pouvez appeler l'émetteur de ce module (par exemple, l'événement click) et modifier le modèle associé à ce module en modèle secondaire.

0
hamid_reza hobab