Обработайте 'this' в слушателе событий - PullRequest
0 голосов
/ 22 ноября 2011
function Foo(map){
    this.map = map;
}  
Foo.prototype = {
    onclick: function(e){
        this.bar(e.point);
    },  
    bar: function(point){
        // do something with point
    },  
    start: function(){
        this.map.addEvent("click", this.onclick);
    },
    stop: function(){
        this.map.removeEvent("click", this.onclick);
    }
};  

, но в onclick, this привязано к map.Я хотел бы, чтобы он был привязан к экземпляру Foo.
обратите внимание, что я не могу использовать анонимную функцию в качестве второго параметра addEvent, потому что мне нужно удалить слушателя позже.

Ответы [ 4 ]

2 голосов
/ 22 ноября 2011

В start() создайте замыкание, которое ссылается на внешний объект через локальный псевдоним:

start: function(){
    var self = this;
    this._handlerFunc = function(){ self.onclick.apply(self, arguments); };
    this.map.addEvent("click", this.handlerFunc);
},
stop: function(){
    this.map.removeEvent("click", this._handlerFunc);
}
1 голос
/ 22 ноября 2011

Это должно дать желаемый результат. Создав объект внутри анонимной функции, вы можете получить ссылку на него.

Foo.prototype = (function() {
    var f = { }
    f.onclick = function(e){
        f.bar(e.point);
    };
    f.bar = function(point){
        // do something with point
    };  
    f.start = function(){
        this.map.addEvent("click", f.onclick);
    };
    f.stop = function(){
        this.map.removeEvent("click", f.onclick);
    };
    return f;
})();  

Пример - http://jsfiddle.net/infernalbadger/Ypgh5/ (Не обращайте внимания на содержание предупреждения, важно, чтобы оно было там!)

0 голосов
/ 22 ноября 2011

этот ответ похож на ответ Ричарда Д., но, поскольку мы хотим, чтобы прототип возвращал новый объект, мы могли бы инициализировать его как один:

Foo.prototype = new function() {
    var self = this;
    this.onclick = function(e){
        this.bar(e.point);
    };
    this.bar = function(point){
        // do something with point
    };  
    this.start: function(){
        this.map.addEvent("click", this.onclick);
    };
    this.stop: function(){
        this.map.removeEvent("click", this.onclick);
    };
    // can use the "self" reference in a callback
    this.someEvent = setTimeout(function(){
        console.log(self);// can't use this here    
    },100);
};  
0 голосов
/ 22 ноября 2011

Вы можете изменить способ вызова обработчика событий.Например (если вы используете jQuery):

$("foo").click((function () {
    var fooObject = new Foo;
    return function (evt) {
        fooObject.onclick.call(fooObject, evt);
    };
}()));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...