2

私はJavaScriptクラスを持っています:

<html>

<head>
    <script src="MicrosoftAjax.js" type="text/javascript"></script>
    <script src="jquery-1.6.4.min.js" type="text/javascript"></script>

</head>

<body>

<script type="text/javascript">

var ClientControl = function () {
    //some instance-specific code here
};

ClientControl.prototype = {
    initialize: function () {
        this.documentClickedDelegate = $.proxy(this.documentClicked, this);
        //this.documentClickedDelegate = Function.createDelegate(this, this.documentClicked); // from MicrosoftAjax
    },

    bind: function() {
        $(document).bind("click", this.documentClickedDelegate);
    },

    unbind: function() {
        $(document).unbind("click", this.documentClickedDelegate);
    },

    documentClicked: function() {
        alert("document clicked!");
    }
};

var Control1 = new ClientControl();
Control1.initialize();
var Control2 = new ClientControl();
Control2.initialize();

Control1.bind();
Control2.bind();

Control1.unbind();
//Control2`s documentClickedDelegate handler, if created with $.proxy, already is unbound!

</script>
</body>
</html>

したがって、問題は、FIRST Control1オブジェクトのunbind ()メソッドが呼び出されると、 $ 。proxy()メソッドで作成されている場合、両方のオブジェクトの両方のdocumentClickedDelegateハンドラーのバインドが解除されることです。したがって、jqueryイベントシステムは、$。proxy()メソッドに渡されるコンテキストが異なるにもかかわらず、これらのハンドラーは同じであると見なします。

documentClickedDelegateハンドラーがFunction.createDelegate -MicrosoftAjaxLibraryのメソッドを使用して作成されている場合、すべてが正常に機能します。ハンドラーは異なります。

$ .proxyは、渡されたさまざまなコンテキストに対して同一のプロキシ関数を作成することが判明しました。公式サイトから:

「ただし、jQueryのイベントバインディングサブシステムは、バインド解除する関数を指定するために使用されるときに追跡するために、各イベント処理関数に一意のIDを割り当てることに注意してください。jQuery.proxy()で表される関数は、異なるコンテキストをバインドするために使用される場合でも、イベントサブシステムによる単一の関数。間違ったハンドラーのバインド解除を回避するには、バインド解除中にプロキシ関数を指定するのではなく、バインドとバインド解除に一意のイベント名前空間(「click.myproxy1」など)を使用します。」

名前空間はインスタンス固有ではなくタイプ固有のイベントを分離するため、私の場合はこれを行うべきではありません。

以下のスクリーンショットは、$。proxyが同一のGUID = 1のハンドラーを作成し、Function.createDelegateが異なるGIUD(guid=1およびguid=2 )のハンドラーを作成することを示しています。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

ここに画像の説明を入力してください

ここに画像の説明を入力してください

したがって、最初のケースで1つを削除すると、両方が削除されますが、これは実行しないでください。

私の質問は、jqueryにFunction.createDelegateに類似したものはありますか?1つの機能だけに別のMicrosoftAjaxライブラリ全体を使用したくありません。または、この問題の一般的な解決策-ハンドラーが異なることをjqueryに伝える方法。ご回答ありがとうございます。

4

1 に答える 1

6

イベントに名前空間を付ける必要があります。簡単な例:

var counter = 0;

ClientControl.prototype = {
    initialize: function () {
        this.documentClickedDelegate = $.proxy(this.documentClicked, this);
        this.num = counter++;
    },
    bind: function() {
        $(document).bind("click.proxy" + this.num, this.documentClickedDelegate);
    },
    unbind: function() {
        $(document).unbind("click.proxy" + this.num, this.documentClickedDelegate);
    },
    documentClicked: function() {
        alert("document clicked!");
    }
}

これが動作中のバージョンです。ドキュメントの任意の場所をクリックすると、アラートが1つ表示されます。名前空間がないと、2になります。

于 2012-02-06T08:07:31.060 に答える