打字稿装饰顺序;在MethodDecorator中获取ClassDecorator信息

时间:2018-02-02 20:09:48

标签: typescript

由于decorator evaluation表示ClassDecorator是最后一次,如何获取来自MethodDecorator的{​​{1}}信息?

一个例子是ClassDecorator装饰器,它为该控制器内的所有路径添加前缀。像这样:

@Controller(prefix: string)

使用此代码,const Controller = (prefix: string) : ClassDecorator => { return target => { Reflect.defineMetadata('prefix', prefix, target); }; }; const Get = (path: string) : MethodDecorator => { return (target, propertyKey, descriptor) => { // add this route to the router, prefixed with the `prefix` metadata from the controller }; }; @Controller('/foo') class Foo { @Get('/bar') bar() { } } prefix的{​​{1}}元数据为target

1 个答案:

答案 0 :(得分:1)

正如我评论的那样,您应该为每个调用Get定义元数据,在那里存储您需要的内容(通常,如果需要,可以存储属性键和描述符;否则,只存储实际内容需要)。然后,在对Controller的调用中,读入所有元数据并使用它执行您想要的操作。例如:

import "reflect-metadata";

// stuff to store with each call to Get
interface GetMethodInfo {
  propertyKey: string | symbol;
  descriptor: TypedPropertyDescriptor<any>
}

const Get = (path: string) : MethodDecorator => {
  return (target, propertyKey, descriptor) => {
    if (!Reflect.hasMetadata('get-methods',target)) {
      // store an array if it's not there already
      Reflect.defineMetadata('get-methods', [], target);
    } 
    const getMethods: Array<GetMethodInfo> = Reflect.getMetadata('get-methods', target);
    // push the new information into that array
    getMethods.push({propertyKey: propertyKey, descriptor: descriptor})    
  };
};

const Controller = (prefix: string) : ClassDecorator => {
  return target => {
    // read in the array from the metadata (may be undefined if no calls to Get)
    const getMethods: Array<GetMethodInfo> = Reflect.getMetadata('get-methods', target) || []; 
    getMethods.forEach(getMethodInfo => {
      // add this route to the router, prefixed with the `prefix` metadata from the controller
    })
  };
};


@Controller('/foo')
class Foo {
  @Get('/bar')
  bar() {
  }
}

希望有所帮助。祝你好运。