如何首先执行类装饰器

我有两个装饰器,一个装饰器放置在一个类上,一个装饰器放置在一个方法上。我对执行顺序感到困惑。为什么在类装饰器之前调用方法装饰器?反正有什么改变吗?

function ClassDecorator() {
  return (target: any): void => {
    console.log('Class decorator')
  }
}

function MethodDecorator() {
  return (target: any,method: string): void => {
    console.log('Method decorator: ' + method)
  }
}

@ClassDecorator()
class A {

    @MethodDecorator()
    public method() {

    }

}

TypeScript Playground


我的特定问题

我有一个名为App的主类,在该类中有一个引用了我的类的数组。我无法从方法装饰器获取该数组中的现有类,因为它是在类装饰器甚至已将该类添加到数组之前执行的。另外,方法装饰器需要父装饰器提供一些值。例如根http路径,因为方法装饰器可以扩展该路径。

例如:@ClassDecorator('/home')@MethodDecorator('/profile')应该添加一条路由/home/profile,但是我得到了两个数组项,一个带有home,另一个带有profile,因为装饰器按照它们的顺序运行。

export class App {
  private readonly routes: Route[] = []

  // Called by the class decorator  
  public addController(controller: new () => any,url: string): void {
    let route = this.routes.find(route => route.controller instanceof controller)
    if (!route) {
      route = new Route()
      this.routes.push(route)
    }
    route.controller = controller
    route.rootPath = url
  }

  // Called by the method decorator
  public addRouteMethod(controller: new () => any,method: Method,url: string,command: string): void {
    let route = this.routes.find(route => route.controller instanceof controller)
    if (!route) {
      route = new Route()
      this.routes.push(route)
    }
    route.controller = controller
    route.commands.push(new Command({
      controller,command,method,path: path.posix.join(route.rootPath,url)
    }))
  }
}

运行应用程序后,我将拥有两个项目的数组,而实际上它应该是一个包含一个项目的数组,其中第二个项目是第一个项目的子项目。我确实知道如何解决此问题,但是我希望类装饰器首先执行任何一种方法来实现这一点?

chunbaise0601 回答:如何首先执行类装饰器

TypeScript decorator documentation specifies the order

  1. 参数修饰符,后跟方法,访问器或属性修饰符将应用于每个实例成员。
  2. 参数修饰符,后跟方法,访问器或属性修饰符将应用于每个静态成员。
  3. 参数修饰符应用于构造函数。
  4. 班级装饰器应用于班级

但是所有评估都在每次调用之前完成(根据文档)。您可以用它在评估步骤中完成类工作,在调用步骤中完成方法吗?

本文链接:https://www.f2er.com/2556869.html

大家都在问