2012-01-24 25 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

最もエレガントな解決策がある:

+0

私は解決策を見つけました。(C#で使われていた)デリゲートに基づいたものと基本的に同じです:http://odetocode.com/Blogs/scott/archive/2007/07/04/javascripts-slippery-this-reference- and-other-monsters-in-the-closet.aspxを参照してください。どうもありがとう。 – DraganS

+0

これはまさに私のコードがしていることです。 – SoWeLie

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

bindを使用することもできますが、まだ広くサポートされていません。

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 
    })) 

機能の方法を適用する使用する

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

だけでクロージャを使用あなたの無名関数にヒッチがあることに注目してください。これは、クリックハンドラ内で対処が保持されるようにします。

+0

私はそれが好きではありませんが、おそらくJSの唯一の解決策です。ありがとう。 – DraganS

関連する問題