jquery bind / trigger в прототипном сценарии наследования. Не могу вызвать события на нужном объекте - PullRequest
0 голосов
/ 15 февраля 2011

Я пытаюсь обернуть голову, используя связывание / триггер в сценарии наследования. Вот что я получил:

  var MyApp = {};

  MyApp.GrandParent = function (){
      var self = Object.create({}), $self = $(self);

      self.doFoo = function(){
          console.log('Just to asure we can call from child to grandparent');
          $(this).trigger('Happened');
          //$self.trigger('Happened'); //Why doesn't it work this way
      };

      return self;
  }

  MyApp.Parent = function(){
      var self = Object.create(MyApp.GrandParent()), $self = $(self);

      self.doSomething = function(){
          console.log('Just to asure we can call from child to parent');
          $(this).trigger('SomethingHappened');
          //$self.trigger('SomethingHappened'); //Why doesn't it work this way
      };

      return self;
  }

  MyApp.Child = function(){
      var self = Object.create(MyApp.Parent()), $self = $(self);

      $self.bind('SomethingHappened', function(){
          console.log('Client logs: SomethingHappened');
      });

      $self.bind('Happened', function(){
          console.log('Client logs: Happened');
      });

      return self;        
  }

  var foo = new MyApp.Child();
  foo.doSomething();
  foo.doFoo();

Рабочий пример: http://jsfiddle.net/cburgdorf/8fWta/12/

Как видите, у нас есть цепочка наследования, начинающаяся от прародителя, а не от родителя к ребенку. Оно работает. Однако я просто не понимаю, почему я не могу вызвать события на объекте $ self. Неправильно стрелять по ним на $ (это).

То, что я хочу заархивировать, - это поддерживать цепочку прототипов в рабочем состоянии и запускать события для объекта $ self. Думаю, мне нужно использовать что-то вроде $ .proxy, но у меня действительно нет подсказки.

Я знаю, что я мог бы сделать это так http://jsfiddle.net/cburgdorf/8fWta/11/ но я бы предпочел, чтобы цепочка прототипов работала ...

Ответы [ 2 ]

2 голосов
/ 15 февраля 2011

Энди Эдинборо прав насчет var self != this.

Похоже, вы хотите сохранить ссылку на jQuery-оболочку вокруг экземпляров вашего объекта, поэтому я использовал шаблон веса (избегает создания свойства на экземпляре объекта для хранения оболочки jQuery) .Вы можете прочитать больше об этом в блоге Джеймса Падолси .

Я также убрал ваш код:

(function(window) {

  var flyweight = $([1]);

  /*--------------------------------------------------------------------------*/

  function GrandParent() {
    /* empty constructor */
  }

  function Parent() {
    /* empty constructor */
  }

  function Child() {
    flyweight[0] = this;
    flyweight.bind('SomethingHappened', function(){
      console.log('Client logs: SomethingHappened');
    })
    .bind('Happened', function(){
      console.log('Client logs: Happened');
    });
  }

  /*--------------------------------------------------------------------------*/

  // setup inheritance
  Parent.prototype = Object.create(GrandParent.prototype, {
    'constructor': {
      'configurable': true,
      'writable': true,
      'value': Parent
     }
  });

  Child.prototype = Object.create(Parent.prototype, {
    'constructor': {
      'configurable': true,
      'writable': true,
      'value': Child
     }
  }); 

  // add methods
  GrandParent.prototype.doFoo = function(){
    flyweight[0] = this;
    flyweight.trigger('Happened');
  };

  Parent.prototype.doSomething = function(){
    flyweight[0] = this;
    flyweight.trigger('SomethingHappened');
  };

  /*--------------------------------------------------------------------------*/

  // expose
  window.MyApp = {
    'GrandParent': GrandParent,
    'Parent': Parent,
    'Child': Child
  };
}(this));

Проверка использования:

var foo = new MyApp.Child;
var bar = new MyApp.Child;

$(bar).bind('SomethingElse', function() {
  console.log('Client logs: SomethingElse');
});

foo.doFoo(); // Client logs: Happened
foo.doSomething(); // Client logs: SomethingHappened

$(bar).trigger('SomethingElse'); // Client logs: SomethingElse
$(foo).trigger('SomethingElse'); // Nothing happens \o/
1 голос
/ 15 февраля 2011

Я думаю, что проблема в вашем Object.create() методе: self! == this.Похоже, что self используется как прототип для создаваемого экземпляра, а на самом деле это не тот же самый экземпляр, который возвращается.

Похоже, это то, что происходит в Child:

  1. MyApp.GrandParent() возвращает экземпляр GrandParent - мы назовем его a.
  2. Поля и функции a используются для распространения нового экземпляра Parent - мы назовем его b.
  3. Поля и функции b используются для распространенияновый экземпляр Child - c.

Таким образом, ссылка $self в MyApp.GrandParent.doFoo на самом деле является ссылкой на a - исходный объект, а this - ссылкой на c - текущий объект.Вот почему $(this).trigger(...) работает, а $self.trigger(...) - нет.

В этой скрипке http://jsfiddle.net/andyedinborough/s8hV7/1/, Я написал функцию Object.create(...), чтобы просто вернуть экземпляр, который ей был дан, и $self.trigger(...)работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...