Наследование Iron-Router RouteController: почему хук родительского контроллера запускается раньше дочернего?

#meteor #iron-router

#метеор #железный маршрутизатор

Вопрос:

Я работал с фантастическим пакетом Iron-Router (0.7.1) для Meteor (0.8.1.3) и столкнулся с чем-то, что кажется несколько нелогичным. Я привел пример ниже.

Следующий код был написан в контексте предоставленных Tinytests железного маршрутизатора. https://github.com/EventedMind/iron-router/blob/devel/test/both/route_controller.js

 var Parent = RouteController.extend({
  onBeforeAction: function(pause) {
    console.log('I'm in the parent!');
    pause();
  }
});

var Child = Parent.extend({
  onBeforeAction: function(pause) {
    console.log('I'm in the child!');
    pause();
  }
});

var inst = new Child(Router, route, {});
inst.runHooks('onBeforeAction');
  

В результате теста дочерний элемент распечатал «Я в родительском»
Я ожидал, что дочерний элемент распечатает «Я в дочернем элементе»

Я чувствую, что при объектно-ориентированном программировании было бы более естественным, чтобы дочернее onBeforeAction переопределяло родительское.

При этом, если это сделано намеренно, как я могу изменить порядок перехватов и запустить только дочернее onBeforeAction?

Ответ №1:

Похоже, это сделано намеренно:

https://github.com/EventedMind/iron-router/blob/devel/lib/route_controller.js#L97

 // concatenate together hook arrays from the inheritance
// heirarchy, starting at the top parent down to the child.
var collectInheritedHooks = function (ctor) {
  var hooks = [];

  if (ctor.__super__)
    hooks = hooks.concat(collectInheritedHooks(ctor.__super__.constructor));

  return Utils.hasOwnProperty(ctor.prototype, hookName) ?
    hooks.concat(ctor.prototype[hookName]) : hooks;
};
  

Если вы не хотите, чтобы родительский хук запускался, похоже, вам придется пропустить использование наследования и сделать что-то вроде смешивания общих функций с различными контроллерами.