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