在 Angular 9 中如何强制 http 客户端响应模型中的属性日期类型?

Dab*_*bas 6 typescript angular

我正在开发 Angular 9 项目,我收到的响应之一包含 type 属性Date,但是当我发送请求时:

// MyModel
class MyModel {
   prop: string;
   myDate: Date;
}

// request sent like
this.http.get<MyModel>(url);
Run Code Online (Sandbox Code Playgroud)

响应正确,但属性填充为stringISO 格式(例如:2020-11-24T19:48:20.3637502)(因为在 JSON 中没有 的类型Date)。我需要的是,每当我创建属性的实例MyModel或为其赋值时myDate,属性始终为Date.

map除了收到响应后执行 a 之外,还有其他方法可以做到这一点吗?

我尝试了这个但没有用:

class MyModel {
   prop: string;
   private _myDate: Date;
   public get myDate() {
      return this._myDate;
   };
   public set myDate(val) {
      this._myDate = new Date(val);
   };
}
Run Code Online (Sandbox Code Playgroud)

Les*_*iak 11

最简单的方法是映射返回的数据并手动进行修改。

\n
this.httpClient.get<DataModel>("/api/getData")\n  .pipe(\n    map((data)=>{\n      data.date1 = new Date(data.date1);\n      data.date2 = new Date(data.date2);\n      data.date3 = new Date(data.date3);\n      return data;\n    })\n  );\n
Run Code Online (Sandbox Code Playgroud)\n

请注意,我有点作弊 - Date 构造函数可以将字符串和 Date 作为参数。一般来说,映射步骤的结果可以具有与接收到的响应不同的类型。

\n

或者,您可以使用 Http 拦截器。

\n

请参阅Angular 应用程序中的日期处理(第 2 部分\xe2\x80\x8a-\xe2\x80\x8aAngular Http 客户端和 Ngx Datepicker)

\n

此外,正如您所注意到的,您为 http get 指定的类型不会以任何方式强制执行。您会收到 json 反序列化的结果。

\n

请注意,如果您使用 aclass而不是 atype作为数据模型,这会特别棘手。即使您收到的字段符合您的预期,原型链也不会建立,因此对收到的对象的任何方法调用都会导致运行时错误。

\n

这也解释了为什么您的尝试get失败set了 - 您收到的对象不是MyModel类的实例。

\n

我的建议是

\n
    \n
  • 将响应数据建模为type(或interface)
  • \n
  • 如果需要的话通过 Observable.pipe 转换数据
  • \n
  • 如果您需要一个类作为数据模型,请将响应映射到上一步中的类。
  • \n
\n