Получение оригинала this в объекте для обработчиков событий jQuery и т. Д. При использовании наследования классов - PullRequest
1 голос
/ 10 октября 2009

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

Я начал с того, что сделал следующее:

jQuery.myBase = {
    foo: 'bar',
    bar: function() { ... }
}

jQuery.fn.myPlugin = function() {
   $.extend( this, jQuery.myBase, {
       oof: 'rab',
       rab: function() { ... }
  }
}

Это все работает нормально, я могу получить доступ к базовым методам и свойствам через this. До тех пор, пока я не попытаюсь добавить что-то вроде обработчика событий jQuery (и т. Д.), Который применяет цель события к this.

Итак, со следующим:

jQuery.myBase = {
    bar: function() { ... }
}

jQuery.fn.myPlugin = function() {
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           jQuery('#someEl').click( this.onClick );
       },

       onClick: function(e) {
           // this now references the element I bound the event to (<div id="someEl" />)
           // so the following doesn't work
           this.bar();
       }
  }
}

Я нашел несколько вещей для создания классов и наследования, которые работают с jQuery (например, один Джон Резиг и DUI ), но те будут / будут испытывать ту же проблему .

Так после всего этого, как мне добраться до оригинального this в этих ситуациях?

Обновление: Обработчик событий (и т. Д.) Может быть либо в jQuery.myBase, либо в самом плагине.

Ответы [ 4 ]

2 голосов
/ 10 октября 2009

Вам нужна ссылка на нее в соответствующем объеме.

jQuery.fn.myPlugin = function() {
   var $this = this;  // Scope it up!
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           jQuery('#someEl').click( this.onClick );
       },

       onClick: function(e) {
           $this.bar();
       }
  }
}
0 голосов
/ 10 октября 2009

Похоже, они решают эту проблему в jQuery , который должен быть частью 1.3.3 согласно комментариям

0 голосов
/ 10 октября 2009

Другой альтернативой может быть использование метода-прототипа с функцией bind() (которая на самом деле делает то же самое, что и мой другой ответ, но более чистым способом), как указано в в этом вопросе , например:

if (!Object.bind) {
    Function.prototype.bind= function(owner) {
        var that= this;
        var args= Array.prototype.slice.call(arguments, 1);
        return function() {
            return that.apply(owner,
                args.length===0? arguments : arguments.length===0? args :
                args.concat(Array.prototype.slice.call(arguments, 0))
            );
        };
    };
}


jQuery.fn.myPlugin = function() {
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           jQuery('#someEl').click( this.onClick.bind( this ) );
       },

       onClick: function(e) {
           this.bar(); // this works
       }
  }
}
0 голосов
/ 10 октября 2009

Единственный способ, которым я думал об этом, который мне не очень нравится и, таким образом, задает вопрос, - это следующее:

jQuery.myBase = {
    bar: function() { ... }
}

jQuery.fn.myPlugin = function() {
   jQuery.extend( this, jQuery.myBase, {
       init: function() {
           var self = this;
           jQuery('#someEl').click( function(e) {
                this.onClick.apply( self, arguments );
           };
       },

       onClick: function(e) {
           // this works
           this.bar();
       }
  }
}
...