如何自动将YYYY-MM-DD字符串从HTTP响应转换为Date



在Angular应用程序中,我从服务器获取一个JSON,其中包含一个日期,该日期与开发人员工具中的"2022-08-05"类似->网络->回答

使用HTTP请求,我将JSON放入以下接口:

export interface Movie {
id: number
title: string
releaseDate: Date
director: string
description: string
}

执行movie.releaseDate.getFullYear()时,控制台中显示以下错误:movie_r2.releaseDate.getFullYear is not a function

然后,我尝试使用一个带有属性装饰器的类,但这也不起作用
之后,我尝试了getter和setter,但我得到了相同的错误。


// function asDate(target: Object, propertyKey: string) {
//   let value: string;
//   console.log("asDate() called");
//
//   Object.defineProperty(target, propertyKey, {
//     get: () => new Date(value),
//     set: (newValue) => value = newValue
//   });
// }
export class Movie {
id: number
title: string
// @asDate
private _releaseDate: Date
director: string
description: string

constructor(id: number, title: string, releaseDate: Date, director: string, description: string) {
console.log("constructor called");
this.id = id;
this.title = title;
this._releaseDate = new Date(releaseDate);
this.director = director;
this.description = description;
}
get releaseDate(): Date {
console.log("called getter");
return new Date(this._releaseDate);
}
set releaseDate(releaseDate: Date) {
console.log("called setter");
this._releaseDate = new Date(releaseDate);
}
}

为什么描述符、构造函数、getter、setter中的console.log语句从未被调用?

如何在Movie类/接口/类型级别编写一些代码,以便对于任何包含Movie类型的HTTP请求,字段releaseDate将包含Date类型的对象(而不是字符串(?我有多个带有Movie接口/类的HTTP请求,所以我对独立于HTTP请求的解决方案感兴趣。这意味着我写过一次,可以根据任何要求使用。

将类型any(即来自http请求的内容(强制为type(接口或类(并不意味着它会自动转换任何字段,甚至检查假设是否正确。

为了实际将字符串转换为Date,您需要调用转换代码。例如,当使用接口时,您可以执行以下操作:

this.http.get('api.url').pipe(
map(response => ({
...response, 
releaseDate: new Date(response.releaseDate)
}),
);

或以下内容,当使用类时:

this.http.get('api.url').pipe(
map(response => new Movie(response.id, response.releaseDate, ...)),
);

100%在同一页面上:这是如何工作的:

// this is a type that comes from API:
export interface MovieDTO {
id: number
title: string
releaseDate: string
...
}
// this is a type you would like to have after the transformation:
export interface Movie {
id: number
title: string
releaseDate: Date
...
}
// in order to map MovieDTO to Movie you need to actually invoke the mapping. 
// to do so, you can use for instance the spread operator, as follows:
// some.service.ts
getMovie(): Observable<Movie> {
return this.http.get<MovieDTO>('api.url').pipe(
map(response => ({
...response, 
releaseDate: new Date(response.releaseDate)
}),
);
}

或者,如果你想采用类方法,以下是如何使其发挥作用:

// this is a type that comes from API:
export interface MovieDTO {
id: number
title: string
releaseDate: string
...
}
// this is your class:
export class Movie {
public id: string;
public title:string;
public releaseDate: Date;
constructor(data: MovieDTO){
this.id = data.id;
this.title = data.title;
this.releaseDate = new Date(data.releaseDate);
}
}
// in order to map MovieDTO to Movie you need to actually create the object by calling new(...). 
// some.service.ts
getMovie(): Observable<Movie> {
return this.http.get<MovieDTO>('api.url').pipe(
map(response => new Movie(response),
);
}

最新更新