Domyślny format konwersji daty na JSON w aplikacji Angular

Nov 30 2020

Załóżmy, że komponent (wewnątrz aplikacji kątowej) ma kilka reaktywnych formularzy zawierających datepickers (używam mat-datepickerz angular material lib) i inne dane wejściowe. Po kliknięciu przez użytkownika przycisku „Prześlij” wysyłam wartość formularzy do kopii zapasowej (z HttpClient.post). Problem polega na tym, że pola wyboru daty są serializowane jako "2020-11-18T22:00:00.000Z"(oczywiście Date.toJSON()wywoływana jest metoda), podczas gdy zaplecze oczekuje innego formatu.

Zauważ, że używam formlybiblioteki lib do budowania moich formularzy, ponieważ zestaw komponentów w każdym formularzu może się różnić. Możesz nie być zaznajomiony, formlyale i tak zestaw datepickerów może się również różnić, więc nie mogę bezpośrednio konwertować pól DatePicker, ponieważ nie znam dokładnej listy pól dat w miejscu, do którego wysyłam wartość formularzy.

Czy istnieje eleganckie rozwiązanie mojego problemu? Nie możesz wymyślić czegoś lepszego niż małpa łatanie Date.prototype.toJSON()lub zapętlanie obiektów wysyłanych na serwer, sprawdzenie typu pól i zmiana pola, jeśli to jest Date? Nie mogę znaleźć sposobu, aby ustawić format wartości wyjściowej przez DatePicker ani w materiale, ani w formie.

Odpowiedzi

1 ibenjelloun Dec 04 2020 at 15:23

Wdrożenie ControlValueAccessor byłoby eleganckim rozwiązaniem. Pomysł polega na utworzeniu komponentu selektora dat, który pobiera format daty jako dane wejściowe i odsyła format jako wynik.

W tym celu wystarczy utworzyć nowy komponent, który nazwałbym na MatDatepickerWrapperComponentpotrzeby tego przykładu. Szablon tego komponentu byłby niczym innym jak selektorem dat materiałów:

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

Po stronie komponentu będziesz musiał zaimplementować ControlValueAccessor i wykonać potrzebne transformacje:

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

Możesz teraz dodać nowy komponent do formularza w taki sam sposób, w jaki dodałeś oryginalny.

Oto działający przykład stackblitz.

1 RobinDijkhof Dec 04 2020 at 05:26

Spróbowałbym użyć przechwytywacza HTTP. Myślę, że możesz użyć swojego przechwytywacza, aby zmienić wszystkie daty w ciele na coś innego.

wprowadź opis linku tutaj jest przykładem działania przechwytywacza. W przykładzie dodawany jest nagłówek. Tutaj i tutaj mamy przykład modyfikacji ciała.

1 Becike Dec 04 2020 at 15:03

Miałem ten sam problem. Mogłem rozwiązać ten problem, zastępując konwerter dat JSON w komponencie aplikacji .:

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

Wywołuję tę funkcję raz w konstruktorze komponentu aplikacji. Możesz zastosować i logikę wewnątrz funkcji, ale pamiętaj, aby powrócić z bieżącym ciągiem.