【问题标题】:How to Create a Simple Typescript Metadata Annotation如何创建简单的 Typescript 元数据注释
【发布时间】:2016-10-31 08:26:51
【问题描述】:

我有一些字段需要在发送到服务器端之前进行格式化。

所以,我想使用自定义序列化器序列化我的 typescript 类的一些字段,这样会很理想:

export class Person {
    @serializeWith(MyDateSerializer)
    private date: Date;
}

post(url, value) {
    this.http.post(url, JSON.stringfy(value, (key, val) => {
       if (//value has serializeWith annotation) {
           return //serialize with custom serializer
       }
    }));
}

任何与此相近的东西都是可以接受的,欢迎任何帮助。 谢谢

【问题讨论】:

    标签: json serialization typescript angular decorator


    【解决方案1】:

    我下面的解决方案建立在:

    1. TypeScript Decorators
    2. Metadata spec (early stage/experimental)

    先决条件:

    1. 在您的 tsconfig.json 或命令行中启用 TypeScript 中的装饰器和装饰器元数据支持:

    tsconfig.json

    {
        "compilerOptions": {
            "target": "es5", // you have to target es5+
            "experimentalDecorators": true,
            "emitDecoratorMetadata": true
            // ....
        }
        // ...
    }
    
    1. 安装reflect-metadata

      npm install --save-dev reflect-metadata

    serializerWith装饰者(厂)

    装饰器工厂是接受一个或多个参数并返回 TypeScript 在生成的 JavaScript 代码中使用的装饰器函数的东西。

    我选择将序列化函数直接传递到我的装饰器工厂,并使用元数据规范的reflect-metadata 实现将序列化函数与属性相关联。我稍后会检索它并在运行时使用它。

    function serializeWith(serializer: (input: any) => string) : (target: any, propertyKey: string) => void {
        return function(target: any, propertyKey: string) {
            // serialization here is the metadata key (something like a category)
            Reflect.defineMetadata("serialization", serializer, target, propertyKey);
        }
    }
    

    使用

    鉴于此序列化程序:

    function MyDateSerializer(value : any) : string {
        console.log("MyDateSerializer called");
        return "dummy value";
    }
    

    然后我们可以像这样应用装饰器工厂:

    import "reflect-metadata"; // has to be imported before any decorator which uses it is applied
    
    class Greeter {
        @serializeWith(MyDateSerializer)
        public greeting : string;
    
        constructor(message: string) {
            this.greeting = message;
        }
    }
    

    我们可以像这样获取和使用序列化器:

    var greetingInstance = new Greeter("hi");
    
    var serializerFunc : (input: any) => string = Reflect.getMetadata("serialization", greetingInstance, "greeting");
    
    serializerFunc(greetingInstance.greeting);
    

    示例

    ma​​in.ts

    import "reflect-metadata";
    
    function serializeWith(serializer: (input: any) => string) : (target: any, propertyKey: string) => void {
        return function(target: any, propertyKey: string) {
            console.log("serializeWith called: adding metadata");
            Reflect.defineMetadata("serialization", serializer, target, propertyKey);
        }
    }
    
    
    function MyDateSerializer(value : any) : string {
        console.log("MyDateSerializer called");
        return "bla";
    }
    
    class Greeter {
        @serializeWith(MyDateSerializer)
        public greeting : string;
    
        constructor(message: string) {
            console.log("Greeter constructor");
            this.greeting = message;
        }
    }
    
    var greetingInstance = new Greeter("hi");
    
    var serializerFunc : (input: any) => string = Reflect.getMetadata("serialization", greetingInstance, "greeting");
    
    var serializedValue = serializerFunc(greetingInstance.greeting);
    console.log(serializedValue);
    

    输出

    c:\code\tmp\lll>node build\main.js
    serializeWith called: adding metadata
    Greeter constructor
    MyDateSerializer called
    bla
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-10
      • 1970-01-01
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      相关资源
      最近更新 更多