Как выполнить декоратор класса первым - PullRequest
0 голосов
/ 29 марта 2020

У меня есть два декоратора, один из которых помещается в класс, а другой - в метод. Я смущен порядком исполнения. Почему декоратор метода вызывается перед декоратором класса? Можно ли как-нибудь это изменить?

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


Мой Specifi c Выпуск

У меня есть мастер-класс с именем App внутри этого класса есть массив, в котором есть ссылки на мои классы. Я не могу получить существующий класс в этом массиве от моего метода-декоратора, потому что он выполняется до того, как декоратор класса даже добавил этот класс в массив. Также есть некоторые значения, которые нужны декоратору метода от родительского декоратора. Например, root 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)
    }))
  }
}

Когда я запускаю свое приложение, у меня есть массив из двух элементов, тогда как на самом деле это должен быть массив с одним элементом, где второй элемент является дочерним по отношению к первому элементу. Я знаю, как я могу это исправить, но я хотел бы, чтобы декоратор класса выполнялся первым любым способом для достижения этой цели?

1 Ответ

0 голосов
/ 29 марта 2020

Документация по TypeScript определяет порядок :

  1. . Для каждого элемента экземпляра применяются декораторы параметров, за которыми следуют метод, метод доступа или декораторы свойств.
  2. Для конструктора применяются декораторы параметров.
  3. Декораторы класса применяются для класса

Но все оценки выполняются перед каждым вызовом (согласно документам). Не могли бы вы использовать это для выполнения работы класса на этапе оценки, а метод - на этапе вызова?

...