Domyślny format konwersji daty na JSON w aplikacji Angular
Załóżmy, że komponent (wewnątrz aplikacji kątowej) ma kilka reaktywnych formularzy zawierających datepickers (używam mat-datepicker
z 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 formly
biblioteki lib do budowania moich formularzy, ponieważ zestaw komponentów w każdym formularzu może się różnić. Możesz nie być zaznajomiony, formly
ale 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
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 MatDatepickerWrapperComponent
potrzeby 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.
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.
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.