События jQuery / javascript - обработчик событий прототипа - PullRequest
0 голосов
/ 11 июня 2010

Следующий код не работает, как я интуитивно ожидаю:

function MyObject(input) {
   input.change(this._foo);
   this.X = undefined;
}

MyObject.prototype._foo = function() {
   alert("This code is never called");
   // but if it did
   this.X = true;
}

var test_input = $("input#xyz"); // a random, existing input

var m = MyObject(test_input); // attach handler (or try to)

test_input.change(); // trigger event

alert(m.X); // undefined

Я ожидал бы, что будет вызван _foo() (и, если это когда-нибудь случится, переменная this в _foo() станет экземпляром MyObject.

Кто-нибудь знает, почему это не работает, и какой-либо альтернативный шаблон для передачи объекта в обработчик событий?

Спасибо за чтение.

Brian

Ответы [ 3 ]

4 голосов
/ 11 июня 2010

Как отмечает Кенни, вам не хватает new. Вы также должны убедиться, что this в _foo относится к MyObject экземпляру
Один из способов сделать это: -

function MyObject( input ) {
    var _this = this;
    input.change( function() {
       // explicitly set the `this` in _foo to `_this`
        _this._foo.call( _this );
    });
   this.X = undefined;
}

MyObject.prototype._foo = function( event ) {
   alert("This is called");
   // and 'this', being 'm', has X set to true
   this.X = true;
   // the textbox must be accessed by 'event.target' not 'this' if you need it
}

var test_input = jQuery("input#xyz"); // a random, existing input

var m = new MyObject(test_input); // attach handler (or try to)

test_input.change(); // trigger event

alert(m.X); // true

P.S Вы не можете избежать использования нового оператора, оставив его вне! :)

2 голосов
/ 11 июня 2010

Чтобы создать объект в Javascript, используйте new.

var m = new MyObject(test_input); // attach handler (or try to)
1 голос
/ 11 февраля 2011

Этот вопрос сейчас старый, но есть и другое решение. Как вы уже упоминали, ваша проблема в том, что вы пропустили «new», и ссылка «this» в обработчике события всегда будет элементом, для которого было инициировано событие, а не объектом, обрабатывающим событие.

Поскольку вы используете JQuery, есть простой способ заставить это действовать так, как вы хотите. Используйте метод JQuery.proxy , чтобы установить контекст обработчика событий для использования вашего объекта как «this». В вашем примере вам просто нужно изменить строку

input.change(this._foo);

до

input.change(jQuery.proxy( this, "_foo" )); 

Попробуйте, если вы снова столкнетесь с этой проблемой с JQuery.

...