如何为属性创建TypeScript @Relationship装饰器

时间:2018-02-10 17:16:05

标签: angular typescript

请考虑以下代码:

export class Model {
    constructor(input: any) {
        this.deserialize(input);
    }

    deserialize(input: any): Model {
        Object.assign(this, input);
        return this;
    }
}

export class Body extends Model {
    Success: boolean;
    @Relationship Result: Result;
    //...
}

export class Result extends Model {
    Skip: number;
    Top: number;
    TotalCount: number;
    //...
}

脚本接收json并启动Body类的新实例:

//...
let body = new Body({
    Sucess: true,
    Result: {
        Skip: 0,
        Top: 0,
        TotalCount: 20
        //...
    }
    //...
});

deserialize方法用于将所有可枚举的自有属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

要使Result属性正确启动,deserialize方法需要进行更改:

deserialize(input: any): Model {
    Object.assign(this, input);
    this.Result = new Result(input.Result);
    return this;
}

Model类是通用的并且无法实现所描述的解决方案的问题。

我不想在每个子类上声明deserialize方法。

因为可以使用装饰器“@Relationship”来解决问题吗?

1 个答案:

答案 0 :(得分:0)

是的,有可能。有detailed example,它做了类似的事情,detailed description(俄语),它是如何工作的

简而言之,你应该做下一步:

  1. 在tsconfig中启用emitDecoratorsMetadata并安装reflect-metadata polyfill。
  2. 在装饰器标记字段中,通过调用Reflect.defineMetadata(“SomeUniqueDecoratorKey”,true,target,fieldName)应用元数据
  3. 在反序列化函数中迭代字段,并检查此字段的SomeUniqueDecoratorKey元数据是否为true。如果是,则获取字段类型构造函数并创建新实例。

     var fieldTypeCtor = Reflect.getMetadata("design:type", target, fieldName);
     var newInstance = new fieldTypeCtor(yourData);