Standardformat für die Konvertierung von Datum in JSON in der Angular-App

Nov 30 2020

Angenommen, eine Komponente (innerhalb der Winkel-App) hat mehrere reaktive Formen, die Datepicker (ich verwende mat-datepickeraus Winkelmaterial lib) und andere Eingaben enthalten. Nachdem ein Benutzer auf "Senden" geklickt hat, sende ich den Wert der Formulare an gesichert (mit HttpClient.post). Das Problem ist, dass Datepicker-Felder als serialisiert werden "2020-11-18T22:00:00.000Z"(offensichtlich wird die Date.toJSON()Methode aufgerufen), während das Backend ein anderes Format erwartet.

Beachten Sie, dass ich formlylib zum Erstellen meiner Formulare verwende, da die Anzahl der Komponenten in jedem Formular variieren kann. Sie sind vielleicht nicht vertraut, formlyaber die Anzahl der Datumsauswahlmöglichkeiten kann ebenfalls variieren. Daher kann ich Datumsauswahlfelder nicht direkt konvertieren, da ich die genaue Liste der Datumsfelder an einem Ort nicht kenne, an dem ich den Wert von Formularen sende.

Gibt es eine elegante Lösung für mein Problem? Sie können sich nichts Besseres vorstellen, als Date.prototype.toJSON()auf dem Server gesendete Objekte zu patchen oder zu durchlaufen, die Art der Felder zu überprüfen und das Feld zu ändern, wenn es sich um ein Feld handelt Date? Ich kann weder im Material noch in der Form das Format der von datepicker ausgegebenen Werte festlegen.

Antworten

1 ibenjelloun Dec 04 2020 at 15:23

Die Implementierung von ControlValueAccessor wäre eine elegante Lösung. Die Idee ist, eine Datumsauswahlkomponente zu erstellen, die Ihr Datumsformat als Eingabe verwendet und Ihr Format als Ausgabe zurücksendet.

Dafür müssen Sie nur eine neue Komponente erstellen, die ich MatDatepickerWrapperComponentfür dieses Beispiel aufrufen würde . Die Vorlage dieser Komponente wäre nichts anderes als die Material-Datumsauswahl:

<mat-form-field appearance="fill">
  <mat-label>Choose a date</mat-label>
  <input matInput [matDatepicker]="picker" [(ngModel)]="model" (ngModelChange)="modelChange($event)">
  <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
  <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

Auf der Komponentenseite müssen Sie ControlValueAccessor implementieren und die erforderlichen Transformationen durchführen:

writeValue(value: string): void {
    this.model = transformDateFromMyFormatToIso(value);
}
modelChange(value: string) {
    const transformedValue = transformIsoDateToMyFormat(value);
    this.onChange(transformedValue);
  }

Sie können die neue Komponente jetzt so zu einem Formular hinzufügen, wie Sie die ursprüngliche Komponente hinzugefügt hätten.

Hier ist ein laufendes Stackblitz-Beispiel.

1 RobinDijkhof Dec 04 2020 at 05:26

Ich würde versuchen, einen HTTP-Interceptor zu verwenden. Ich denke, Sie können möglicherweise Ihren Abfangjäger verwenden, um alle Daten im Körper in etwas anderes zu ändern.

Geben Sie hier die Linkbeschreibung ein. Dies ist ein Beispiel für die Funktionsweise des Interceptors. Im Beispiel wird ein Header hinzugefügt. Hier und hier sind ein Beispiel für die Veränderung des Körpers.

1 Becike Dec 04 2020 at 15:03

Ich hatte das gleiche Problem. Ich könnte dies lösen, indem ich den JSON-Datumskonverter in der App-Komponente überschreibe:

overrideToJSONDate() {
    Date.prototype.toJSON = function () {
      return new Date(this).toLocaleString();
    }
  }

Ich rufe diese Funktion einmal im Konstruktor der App-Komponente auf. Sie können innerhalb der Funktion eine Logik anwenden, aber stellen Sie sicher, dass Sie mit der aktuellen Zeichenfolge zurückkehren.