Формат преобразования даты по умолчанию в JSON в приложении Angular
Предположим, что компонент (внутри приложения angular) имеет несколько реактивных форм, содержащих датпикеры (я использую mat-datepickerиз библиотеки материалов angular) и другие входные данные. После того, как пользователь нажал кнопку «Отправить», я отправляю значение формы в резервную копию (с HttpClient.post). Проблема в том, что поля datepicker сериализуются как "2020-11-18T22:00:00.000Z"(очевидно, Date.toJSON()вызывается метод), в то время как бэкэнд ожидает другого формата.
Обратите внимание, что я использую formlylib для создания своих форм, потому что набор компонентов в каждой форме может отличаться. Возможно, вы не знакомы, formlyно в любом случае набор датпикеров также может отличаться, поэтому я не могу напрямую преобразовывать поля датпикера, потому что я не знаю точный список полей даты в месте, куда я отправляю значение форм.
Есть ли элегантное решение моей проблемы? Не можете придумать что-то лучше, чем исправление обезьяны Date.prototype.toJSON()или перебирать объекты, отправленные на сервер, проверять тип полей и изменять поле, если оно есть Date? Я не могу найти способ установить формат вывода значения с помощью datepicker ни в материале, ни в форме.
Ответы
Реализация ControlValueAccessor была бы элегантным решением. Идея состоит в том, чтобы создать компонент выбора даты, который принимает ваш формат даты в качестве ввода и отправляет ваш формат в качестве вывода.
Для этого вам просто нужно создать новый компонент, который я бы назвал MatDatepickerWrapperComponentдля этого примера. Шаблон этого компонента будет не чем иным, как средством выбора даты материала:
<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>
Со стороны компонентов вам нужно будет реализовать ControlValueAccessor и выполнить необходимые преобразования:
writeValue(value: string): void {
this.model = transformDateFromMyFormatToIso(value);
}
modelChange(value: string) {
const transformedValue = transformIsoDateToMyFormat(value);
this.onChange(transformedValue);
}
Теперь вы можете добавить новый компонент в форму так, как если бы вы добавляли исходный.
Вот пример работающего stackblitz.
Я бы попробовал использовать перехватчик HTTP. Я думаю, вы могли бы использовать свой перехватчик, чтобы изменить все даты в теле на что-то другое.
введите описание ссылки вот пример того, как работает перехватчик. В примере добавлен заголовок. Вот и вот пример модификации тела.
У меня такая же проблема. Я мог бы решить эту проблему, переопределив преобразователь даты JSON в компоненте приложения:
overrideToJSONDate() {
Date.prototype.toJSON = function () {
return new Date(this).toLocaleString();
}
}
Я вызываю эту функцию один раз в конструкторе компонента приложения. Вы можете применить и логику внутри функции, но обязательно верните текущую строку.