2

数時間の追加調査を行いましたが、一般的な問題と思われるものの良いパターンをまだ見つけることができません.

私は.Net MVC2アプリに取り組んでいます。私たちのアプリは、メイン ページといくつかの部分ビュー (含まれるページ) で構成されています。各部分ビューは、HTML構造とJS-jQueryガッツで構成されるウィジェットに対応しています。

一部のウィジェットは相互に豊富な相互作用を持っているため、もちろん、jQuery のイベント バインディングを使用して、この効果を実現しています。

データ概要ウィジェット

$(document).bind("DataUpdated", summaryobject.updateTotals());

データ操作ウィジェット

$(document).trigger("DataUpdated");

私たちが抱えている問題は、ユーザーがアプリケーションの一部に移動すると、これらのウィジェット (HTML/DOM) がページから削除され、新しい部分ビューのセットに置き換えられることです。ユーザーが戻ると、ダブル バインディングを作成する jQuery バインディングと共に HTML (視覚的表現) が再読み込みされます。

これまでのところ、私の解決策は不十分に思えます。

(1) バインディングの対象となる DOM オブジェクトにバインドします。

$("#summaryobject").bind("DataUpdated", summaryobject.updateTotals());

これに関する問題は、トリガーするウィジェットが、トリガーする DOM オブジェクトを知る必要が$("#summaryobject")あることです。つまり、どの種類の目的が無効になるかです。

(2) EventBus オブジェクトを作成して、誰がどのイベントをバインドしたかを追跡し、イベントを一度だけバインドできるようにします。私が抱えている問題は、誰が作成したかを追跡できないイベントを保存/バインドするときに、必要に応じて登録を解除できないことです....おそらく、登録されていないイベントは必要ありません。

カスタム イベントを管理するために他のユーザーが使用しているパターンは何ですか?

4

4 に答える 4

1

あなたの問題には2つの良い解決策があります(私は見ることができます).

  1. すべての呼び出しを削除して、またはbindへの単一の呼び出しに置き換えて、アプリケーションで発生するすべてのイベントをリッスンし、それらを適切な場所にルーティングするリスナーを設定します。(つまり、コントローラーを作成します)。delegatelive

  2. イベントのサブスクライブだけでなくサブスクライブも解除できるようにする EventBus を使用します。EventBus でこれを行う最も簡単な方法は、Peter Michaux のEventing scriptです。


/* 
Extremely loosely coupled custom events
Source: 
http://peter.michaux.ca/articles/anonymous-events-extremely-loose-coupling
*/

EventManager = {};

EventManager.events = {};

EventManager.subscribe = function( event_name, subscriber, method_name ) {
    var event = this.events[event_name];
    if ( ! event ) {
        event = this.events[event_name] = [];
    }
    event.push( { s: subscriber, m: method_name } );
    return this;
};

EventManager.unsubscribe = function( event_name, subscriber ) {
    var event = this.events[event_name];
    if ( ! event ) {
        return;
    }
    for ( var i = event.length - 1; i >= 0; i-- ) {
        if ( event[i].s === subscriber ) {
            event.splice( i, 1 );
        }
    }
    return this;
};

EventManager.unsubscribe_all = function( event_name ) {
    delete this.events[event_name];
    return this;
};

EventManager.fire = function( event_name ) {
    var event = this.events[event_name];
    if ( ! event ) {
        return this;
    }
    for ( var i = event.length - 1; i >= 0; i-- ) {
        subscription = event[i];
        subscription.s[subscription.m].apply( subscription.s, arguments );
    }
    return this;
};

この 2 番目の方法の使用例は次のとおりです。

EventManager.subscribe("DataUpdated", summaryobject, "updateTotals");
// ... at some point later on ...
EventManager.fire("DataUpdated");
// Fires `updateTotals` with `this` bound to `summaryobject`
于 2010-10-08T16:53:59.103 に答える
0

私は今のところこれをやった:

私のpagemanagerオブジェクトの下で、私はこのメソッドを書きました

function PageManager() {
    this.eventBusRegistry = [];

    ///<summary>Registers Event if not already bound</summary>
    this.registerForEvent = function (eventName, eventOwner, functionToBind) {
        if (this.eventBusRegistry[eventName + eventOwner] == null) {
            this.eventBusRegistry[eventName + eventOwner] = "BOUND";
            $(document).bind(eventName, functionToBind);
        }
    }
}

私のウィジェットクラスでは、これを行いました。

   ///<summary>Widget</summary>
    function Widget(inWidgetName) {

        //the data you wish to update.
        this.data = {};
        //name of widget
        this.widgetName = inWidgetName;
    }

    Widget.prototype.registerForEvent = function (eventName, functiontoBind) {
       //Session is the instance of PageManager
        Session.registerForEvent(eventName, this.widgetName, functiontoBind);
    };

ウィジェットの任意のインスタンスに対して、registerForEvent を呼び出してイベントをバインドします。

これは完全な解決策とはほど遠いものです。私たちの設計では、JS オブジェクトを登録解除しないため、依然としてメモリ リークが発生します。ただし、オブジェクトはロードされるたびに上書きされるため、最悪の場合、アプリケーション内のすべてのオブジェクトが、使用されていなくても一度だけ登録される可能性があります。

ただし、メソッドをイベントにバインドすると、上書きまたはコースされていないドキュメント オブジェクトにバインドされます。したがって、このコードは再バインドを停止します。まだ少しずさんなセットアップがありますが、その影響は最小限に抑える必要があります。

于 2010-10-08T21:45:02.643 に答える
0

次のようないくつかのことを試すことができます。

  1. イベント タイプの名前空間。このようにして、2 つの特定のビュー インスタンス間にバインディングを作成するのではなく、ビューのタイプ間に一般化された関係を作成できます。上記の例から:

    データ サマリー ウィジェット A

    $(document).bind("DataUpdated.Statistics", summaryobject.updateTotals());
    

    データ操作ウィジェット A

    $(document).trigger("DataUpdated.Statistics");
    

    ここのドキュメントをチェックしてください: http://api.jquery.com/bind/

  2. 新しい DOM / ハンドラーをロードする前に、ウィジェットまたはそれらのグループがアンロードされるたびに、イベント ハンドラーをアンロードします。

于 2010-10-08T16:54:23.840 に答える
0

live()バインディングメソッドを使用してみましたか?

于 2010-10-08T16:55:46.363 に答える