Angular 应用中默认日期到 JSON 的转换格式

Default Date to JSON conversion format in Angular app

假设一个组件(在 angular 应用程序内)有几个包含日期选择器的反应形式(我正在使用 angular material 库中的 mat-datepicker)和其他输入。在用户点击“提交”按钮后,我将表单的值发送到支持(HttpClient.post)。问题是日期选择器字段被序列化为 "2020-11-18T22:00:00.000Z"(显然 Date.toJSON() 方法被调用)而后端需要其他格式。

请注意,我正在使用 formly 库来构建我的表单,因为每个表单上的组件集可能会有所不同。您可能不熟悉 formly 但无论如何,一组日期选择器也可能有所不同,因此我无法直接转换日期选择器字段,因为我不知道发送值的地方的日期字段的确切列表形式。

我的问题有没有优雅的解决方案?想不出比猴子修补 Date.prototype.toJSON() 或遍历服务器上发送的对象更好的方法,检查字段类型并更改字段(如果它是 Date)?我找不到在 material 或 formly 中设置日期选择器输出值格式的方法。

我会尝试使用 HTTP 拦截器。我认为您可以使用拦截器将正文中的所有日期更改为其他日期。

enter link description here is an example of how the interceptor works. In the example, a header is added. and 为正文修改示例

我遇到了同样的问题。 我可以通过覆盖应用程序组件中的 JSON 日期转换器来解决这个问题。:

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

我在应用程序组件的构造函数中调用了一次这个函数。 您可以在函数内部应用和逻辑,但请确保 return 使用当前字符串。

实施 ControlValueAccessor 将是一个优雅的解决方案。这个想法是创建一个日期选择器组件,它将您的日期格式作为输入并将您的格式作为输出发回。

为此,您只需创建一个新组件,在本例中我将其称为 MatDatepickerWrapperComponent。该组件的模板只不过是 material 日期选择器:

<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);
  }

您现在可以按照添加原始组件的方式将新组件添加到表单中。

Here is a running stackblitz example.