【问题标题】:How to create a TypeScript @Relationship decorator for a property如何为属性创建 TypeScript @Relationship 装饰器
【发布时间】:2018-02-11 05:36:39
【问题描述】:

考虑以下代码:

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”解决?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-04-17
      • 2019-07-29
      • 1970-01-01
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 2011-03-15
      • 2018-07-20
      相关资源
      最近更新 更多