Domanda

Ho fatto un paio di ore di ricerca supplementare, ma ancora non riesce a trovare un buon motivo per quello che io penso è un problema comune.

Sto lavorando su un'applicazione .Net MVC2. La nostra applicazione è costituito da una pagina principale poi un certo numero di punti di vista parziali (pagine incluse) ognuna delle viste parziali corrisponde a un widget, comprensivi di un HTML struttura e JS-jQuery budella

Alcuni dei nostri widgets avere interazioni ricche con l'altro in modo ovviamente stiamo usando evento vincolante qualcosa del jQuery per l'effetto di questo:

Dati di sintesi Widget

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

Data Manipulation Widget

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

Il problema che stiamo avendo è che quando un utente accede a parti delle applicazioni questi widget (HTML / DOM) vengono rimossi dalla pagina e sostituire con la nuova serie di viste parziali. Quando un utente si sposta indietro il codice HTML (rappresentazione visiva) viene ricaricato con il legame jQuery che crea un doppio legame.

Finora le mie soluzioni sembrano zoppo a me.

(1) si legano con l'oggetto DOM l'associazione è per:

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

Il problema di questo è che poi il mio innescando esigenze di widget per sapere cosa DOM riserva di trigger su:. $("#summaryobject") che tipo di sconfitte lo scopo

(2) Creare un oggetto EventBus al tratto che legato quali eventi e consentire solo gli eventi da rilegare una volta. Il problema che sto avendo è quando la memorizzazione / vincolanti gli eventi non riesco a tenere traccia di chi lo ha creato in modo da non posso annullare la registrazione, se ho bisogno di .... forse gli eventi non registrati non è necessario evento.

Quali modelli sono altri che utilizzano per gestire gli eventi personalizzati?

È stato utile?

Soluzione 4

ho finito per fare questo, per ora:

sotto il mio oggetto PageManager Ho scritto questo metodo

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

Per la mia classe di widget ho fatto questo.

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

Per ogni istanza di un widget si chiama registerForEvent a eventi bind.

Questo è lontano da una soluzione perfetta. Il nostro progetto avrà ancora perdite di memoria a che noi non annullare la registrazione i nostri oggetti JS. Tuttavia, i nostri oggetti vengono sovrascritte ogni volta che vengono caricati in modo caso peggiore è che ogni oggetto nell'applicazione può essere registrato una volta, anche se non vengono utilizzati.

Tuttavia, vincolante un metodo per una lega evento all'oggetto documento che non viene sovrascritto o corso. Quindi, questo codice ci impedirà di rebinding. Abbiamo ancora un po 'di una configurazione sciatta tuttavia è ramificazioni dovrebbero essere ridotti al minimo.

Altri suggerimenti

Ci sono due buone soluzioni al problema (che posso vedere).

  1. Rimuovi tutte le chiamate bind e sostituirli con una singola chiamata a delegate o live e impostare un listener in ascolto per tutti di eventi che si verificano in l'applicazione e percorsi loro di luoghi appropriati. (In altre parole, creare un controller).

  2. Utilizzare un EventBus che consente eventi da non sottoscritti, così come sottoscritto. Il modo più semplice che ho visto a che fare questo con un EventBus è di Peter Michaux Eventing sceneggiatura .


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

Un esempio di utilizzo di questo secondo metodo sarebbe:

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

Si potrebbe provare un paio di cose, come:

  1. namespacing i tipi di eventi. In questo modo, pur non creando un legame tra due casi vista specifici, è possibile creare un rapporto generalizzato tra i tipi di viste. Dal tuo Nell'esempio qui sopra:

    Dati di sintesi Widget A

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

    Data Manipulation Widget A

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

    Controlla la documentazione qui: http://api.jquery.com/bind/

  2. scarico dei gestori di eventi ogni volta che un widget o gruppo di esse viene scaricata, prima di caricare il nuova DOM / gestori.

Hai provato a usare live() metodo di rilegatura?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top