【问题标题】:Property Decorators in Angular ModelAngular 模型中的属性装饰器
【发布时间】:2019-11-22 13:55:42
【问题描述】:

我有一个 Angular 8 应用程序,它从后端检索一些数据并将其显示在前端。我有一个后端模型和前端模型不完全相同的问题,例如后端模型有一个 SQL 格式的日期字段,而在前端我希望它采用 javascript 友好格式。

所以我想为日期属性创建一个装饰器,而不是在类中创建另一个属性并将其映射到正确的值。所以可视化:

方法 #1:不太聪明的方法:引入具有正确日期格式的新 created 属性:

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 函数被完全忽略,组件模板仍然尝试呈现旧值。所以我的问题是,

  1. 什么可能导致 getter 没有被解雇以使一切正常工作,
  2. getter 能否返回不同的类型(日期)而不是原始字符串:
  3. 最重要的是,装饰器是正确的方法吗?

谢谢

【问题讨论】:

    标签: angular typescript angular-decorator


    【解决方案1】:

    您可以使用 typescript 装饰器 来解决您的问题;

    我认为您的问题已经得到解答,请查看此内容。 How to Create a Simple Typescript Metadata Annotation

    【讨论】:

      【解决方案2】:

      您可以使用class-transformer 库并自动将接收到的 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
      // }
      

      您可以查看库的 README 部分 - 它有多个如何使用它的示例。

      【讨论】:

        猜你喜欢
        • 2017-03-15
        • 1970-01-01
        • 1970-01-01
        • 2020-06-20
        • 2019-05-25
        • 1970-01-01
        • 2019-08-19
        • 1970-01-01
        • 2015-10-23
        相关资源
        最近更新 更多