Angular 角度模型中的属性装饰器

Angular 角度模型中的属性装饰器,angular,typescript,angular-decorator,Angular,Typescript,Angular Decorator,我有一个Angular 8应用程序,它从后端检索一些数据并在前端显示。我有一个问题,后端模型和前端模型不完全相同,例如后端模型有一个SQL格式的日期字段,在前端我希望它是javascript友好的格式 所以我想为date属性创建一个装饰器,而不是在类中创建另一个属性并用正确的值映射它。因此,要形象化: 方法#1:不太聪明的方法:使用正确的日期格式引入新创建的属性: export class Message { id: number; message: string; vi

我有一个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;
      })

    );
  }


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>

导出类消息{
id:编号;
消息:字符串;
访客:访客;
createdAt:string;/*保存后端模型的创建日期*/
created:Date;/*保存前端脚本日期*/
}
/*API调用服务*/
公共getMessages(访问者id:number):可观察{
返回此.httpClient.get(`${API\u URL}/API/SampleData/Messages?visitor=${visitor\u id}`).pipe(
地图(v=>{
v、 model.map(i=>{
i、 created=moment(i.createdAt.replace('T',''),'YYYY-MM-DD HH:MM:ss').toDate();
返回i;
})
返回v;
})
);
}
方法#2:使用属性装饰器的简洁方法:

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

    );
  }


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>


导出类消息{
id:编号;
消息:字符串;
访客:访客;
@DateTransform()
createdAt:string;
}
函数DateTransform(){
返回函数(目标:任意,键:字符串){
defineProperty(目标,键,{
可配置:false,
获取:()=>{
console.log('尝试获取值:'+key);/*此行不触发*/
返回力矩(键替换('T',''),'YYYY-MM-DD HH:MM:ss')。toDate()
}
});
}
}
/*在组件html中*/
{{message.createdAt | amTimeAgo}}
因此,第二种方法看起来像正确的方法,但是,getter函数被完全忽略,组件模板仍然尝试呈现旧值。所以我的问题是,

  • 是什么原因导致getter没有被解雇
  • getter是否可以返回不同的类型(日期)而不是原始字符串:
  • 最重要的是,装饰师是正确的方法吗

  • 感谢您,您可以使用库自动将接收到的JSON转换为实际对象,而不是手动执行此操作。它还允许您指定
    @Transform
    注释/装饰器,以进一步自定义普通
    值的转换方式

    下面是一个例子:

    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
    // }
    

    您可以签出库的部分-它有多个如何使用它的示例。

    您可以使用typescript decorators来解决您的问题

    我想你的问题已经得到了回答,请核对一下