Frage

Ich habe ein paar Stunden zusätzlicher Forschung getan, aber ich kann immer noch nicht ein gutes Muster finden, was ich denke, würde ein häufiges Problem ist.

Ich arbeite an einem .net MVC2 App. Unsere App besteht aus einer Haupt-Seite dann einer Reihe von Teilansichten (inklusive Seiten) jedes der Teilansichten entsprechen einen Widget aus, bestehend aus einer HTML Struktur und JS-jQuery Mut

Einige unserer Widgets haben reiche Wechselwirkungen miteinander, so natürlich wir die jQuery-Ereignis Bindung etwas zu den Auswirkungen dieses verwenden:

Daten Summary Widget

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

Data Manipulation Widget

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

Das Problem, das wir haben, ist, dass, wenn ein Benutzer navigiert zu Teile der Anwendungen diese Widgets (HTML / DOM) von der Seite entfernt werden und mit dem neuen Satz von Teilansichten ersetzen. Wenn ein Benutzer navigiert der HTML (visuelle Darstellung) zurück zusammen mit der jQuery-Bindung neu geladen, die eine doppelte Bindung erzeugt.

Bisher meine Lösungen scheinen lahm zu mir.

(1) bindet an das DOM-Objekt der Bindung ist für:

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

Das Problem dabei ist, dass dann Widget Bedürfnisse meine Triggern zu wissen, was DOM bject triggern. $("#summaryobject") welche Niederlagen Art der Zweck

(2) Erstellen Sie ein EventBus Objekt-Darm-Trakt, die die Ereignisse gebunden und nur erlauben, Ereignisse einmal gebunden zu sein. Das Problem, das ich habe, ist, wenn die Speicherung / die Ereignisse Bindung kann ich nicht nachvollziehen, wer sie erstellt, so kann ich austragen es nicht, wenn ich muß .... vielleicht nicht registrierten Ereignisse nicht Ereignis erforderlich.

Was Muster andere sind mit benutzerdefinierten Ereignisse verwalten?

War es hilfreich?

Lösung 4

ich am Ende tun dies jetzt:

unter meinem Pagemanager Objekt schrieb ich diese Methode

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

Für meine Widgets Klasse Ich tat dies.

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

Für jede Instanz ein Widget Sie registerForEvent zu binden Ereignisse aufrufen.

Dies ist weit von einer perfekten Lösung. Unser Design wird immer noch Speicherlecks in haben, dass wir nicht austragen unsere JS-Objekte. Allerdings sind unsere Objekte jedes Mal, wenn sie geladen werden überschreiben, so schlimmer Fall ist, dass jedes Objekt in der Anwendung einmal registriert werden kann, selbst wenn sie nicht benutzt werden.

Allerdings Bindung ein Verfahren auf ein Ereignis bindet an das Dokumentobjekt, das oder natürlich nicht überschrieben wird. So wird dieser Code uns von rebinding zu stoppen. Wir haben noch ein bisschen wie ein schlampig Setup haben jedoch seine Auswirkungen minimiert werden.

Andere Tipps

Es gibt zwei gute Lösungen für Ihr Problem (das ich sehen kann).

  1. Sie alle Ihre bind Anrufe entfernen und ersetzen sie durch einen einzigen Aufruf an delegate oder live und einen Listener einzurichten, die für hört alle von Ereignissen, die auftreten, in Ihre Anwendung und leitet sie an den entsprechenden Stellen. (Mit anderen Worten, erstellen Sie einen Controller).

  2. Verwenden Sie ein EventBus, die Veranstaltungen sowie abonnierte abgemeldet werden können. Der einfachste Weg, den ich gesehen habe dies mit einem EventBus zu tun ist, Peter Michaux Vielseitigkeit Skript .


/* 
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;
};

Ein Beispiel dieses zweite Verfahren der Verwendung wäre:

EventManager.subscribe("DataUpdated", summaryobject, "updateTotals");
// ... at some point later on ...
EventManager.fire("DataUpdated");
// Fires `updateTotals` with `this` bound to `summaryobject`

Sie könnten ein paar Dinge ausprobieren, wie:

  1. Namespacing Ihre Ereignistypen. Auf diese Weise, wenn auch nicht eine Bindung zwischen zwei Schaffung spezifische Sicht Fällen können Sie schaffen eine verallgemeinerte Beziehung zwischen verschiedenen Arten von Ansichten. Von deiner Beispiel oben:

    Daten Summary Widget A

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

    Data Manipulation Widget A

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

    Überprüfen Sie die Dokumentation hier aus: http://api.jquery.com/bind/

  2. Entladen der Event-Handler immer dann, wenn ein Widget oder eine Gruppe von ihnen entladen wird, der vor dem Laden neuer DOM / Handler.

Haben Sie versucht, live() Bindung Methode?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top