2012-01-24 87 views
0

我想在点击处理程序中使用fnB。有没有优雅的解决方案?谢谢。基于SoWeLie的回答从jQuery'closure'访问外部方法

A = function() { 
    ... 
} 

B = function() { 
    ... 
} 
B.prototype = new A(); 
B.prototype.fnB = function() {} 
B.prototype.fn = function() { 
    // this isntanceof B -> true 
    jQuery(selector).click(function() { 
    this.fnB() // this instance of B -> false, this == $(selector) -> true 
    } 
} 

实现:

EventType = { 
    ButtonClicked: 0 
    ... 
} 

function Delegate(object, method) { 
    return function() { method.apply(object, arguments); } 
} 

function Observable() { 
    this._eventHandlers = {}; 
} 

Observable.prototype = { 
    addListener: function(eventType, listener) { 
     if(!this._eventHandlers.eventType) { 
      this._eventHandlers.eventType = []; 
     } 
     this._eventHandlers.eventType.push(listener); 
    }, 

    removeListener: function(eventType, listener) { 
     if(this._eventHandlers.eventType) { 
      for(var i = this._eventHandlers.eventType.length; --i > -1;) { 
       if(!listener || this._eventHandlers.eventType[i] == listener) { 
        this._eventHandlers.eventType.splice(i, 1); 
       } 
      } 
     } 
    }, 

    fireEvent: function(eventType, data) { 
     if(this._eventHandlers.eventType) { 
      for(var i = 0; i < this._eventHandlers.eventType.length; ++i) { 
       var handleEvent = this._eventHandlers.eventType[i]; 
       if(handleEvent) { 
        handleEvent(this, data); 
       } 
      } 
     } 
    } 
} 

Dialog.Buttons = { ButtonOk: 0, ButtonCancel: 1, ButtonYes: 2, ButtonNo: 3, ButtonClose: 4 }; 
Dialog.prototype = new Observable(); 
Dialog.prototype.bindEvents = function() { 
    $('#dlgButtonOk', this._$el).click(Delegate(this, function() { 
     this.fireEvent(EventType.ButtonClicked, Dialog.Buttons.ButtonOk); 
    })); 
    $('#dlgButtonCancel', this._$el).click(this, function() { 
     this.fireEvent(EventType.ButtonClicked, Dialog.Buttons.ButtonCancel); 
    }); 

$(function() { 
    dialog = new Dialog('.dialogWnd') 
    dialog.addListener(EventType.ButtonClicked, function() {alert(1)}) 
}); 

???? 哎呀!您的编辑无法提交,因为:

您的帖子没有太多的上下文来解释代码段;请更清楚地解释你的情况。 ???

回答

1

最优雅的解决方案是使用应用功能的方法:

var hitch = function (scope, callback) { 
     return function() { 
      return callback.apply(scope, Array.prototype.slice.call(arguments)); 
     } 
    } 

更改您的代码如下所示:

jQuery(selector).click(hitch(this, function() { 
    this.fnB() // this instance of B -> false, this == $(selector) -> true 
    })) 

注意调用匿名函数,这将确保在点击处理程序中保留应付。

+0

我发现了一个解决方案,基本上和你基于代表(在C#中使用)一样:http://odetocode.com/Blogs/scott/archive/2007/07/04/javascripts-slippery-this-reference-和其他妖怪,在最closet.aspx。非常感谢。 – DraganS

+0

是的,这正是我的代码所做的。 – SoWeLie

1
var that = this; 
jQuery(selector).click(function() { 
    that.fnB() 
} 

或者您可以使用bind,但它尚未得到广泛支持。

0

只需使用一个封闭:

B.prototype.fn = function() { 
    // this isntanceof B -> true 
    var that = this; 
    jQuery(selector).click(function() { 
     that.fnB(); 
    }); 
}; 
+0

我不喜欢它,但它可能是JS中唯一可能的解决方案。谢谢。 – DraganS