我有一个 Angular 8 应用程序,它从后端检索一些数据并将其显示在前端。我有一个问题,后端模型和前端模型不完全相同,例如后端模型有一个SQL格式的日期字段,而在前端,我希望它采用javascript友好的格式。
因此,我想为 date 属性创建一个装饰器,而不是在类中创建另一个属性并使用正确的值映射它。所以要可视化:
方法#1:不太聪明的方法:引入具有正确日期格式的新创建的属性:
export class Message {
id: number;
message: string;
visitor: Visitor;
createdAt: string; /* Holds the backend model created date */
created: Date; /* Holds the frontend javscript date */
}
/* API Call in Service */
public getMessages(visitor_id: number) : Observable<Messages> {
return this.httpClient.get<Messages>(`${API_URL}/api/SampleData/Messages?visitor=${visitor_id}`).pipe(
map(v => {
v.model.map(i => {
i.created = moment(i.createdAt.replace('T', ' '), 'YYYY-MM-DD HH:mm:ss').toDate() ;
return i;
})
return v;
})
);
}
方法#2:使用属性装饰器的整洁方法:
export class Message {
id: number;
message: string;
visitor: Visitor;
@DateTransform()
createdAt: string;
}
function DateTransform() {
return function (target: any, key: string) {
Object.defineProperty(target, key, {
configurable: false,
get: () => {
console.log('trying to get value:' + key); /* This line doesnt fire */
return moment(key.replace('T', ' '), 'YYYY-MM-DD HH:mm:ss').toDate()
}
});
}
}
/* And in the component html */
<span class="kt-chat__datetime">{{ message.createdAt | amTimeAgo }}</span>
因此,第二种方法看起来是正确的方法,但是,getter 函数被完全忽略,并且组件模板仍然尝试呈现旧值。所以我的问题是,
- 什么可能导致吸气剂没有被解雇以一切正常,
- getter 是否可以返回不同的类型(日期)而不是原始字符串:
- 最重要的是,装饰器是正确的方法吗?
谢谢
您可以使用打字稿装饰器来解决您的问题;
我想你的问题已经回答了,请查看这个。如何创建简单的打字稿元数据注释
您可以使用类转换器库并将收到的 JSON 自动转换为实际对象,而不是手动执行此操作。它还允许您指定@Transform
注释/修饰器,以进一步自定义普通value
的转换方式。
下面是一个示例:
import {plainToClass} from "class-transformer";
class User {
id: number;
firstName: string;
lastName: string;
@Type(() => Date)
@Transform(value => moment(value), { toClassOnly: true })
date: Moment;
}
const fromPlainUser = {
unkownProp: 'hello there',
firstName: 'Umed',
lastName: 'Khudoiberdiev',
date: '2013-02-08 09:30 '
}
console.log(plainToClass(User, fromPlainUser))
// User {
// unkownProp: 'hello there',
// firstName: 'Umed',
// lastName: 'Khudoiberdiev',
// date: Date Object
// }
您可以查看库的自述文件部分 - 它有多个如何使用它的示例。