Question

Je l'ai fait quelques heures de recherche supplémentaire, mais je ne peux toujours pas trouver un bon modèle à ce que je pense est un problème commun.

Je travaille sur une application .Net MVC2. Notre application se compose d'une page principale puis un certain nombre de vues partielles (pages incluses) chacun des vues partielles correspond à un widget constitué d'une structure HTML et JS jQuery tripes

Certains de nos widgets ont des interactions riches entre eux afin bien sûr, nous utilisons la liaison événement du jQuery de quelque chose à l'effet de ceci:

Sommaire des données Widget

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

Widget Manipulation de données

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

Le problème que nous avons est que comme utilisateur navigue à une partie des applications de ces widgets (HTML / DOM) sont supprimés de la page et les remplacer par la nouvelle série de vues partielles. Lorsqu'un utilisateur navigue le dos HTML (représentation visuelle) est rechargées en même temps que la liaison jQuery qui crée une double fixation.

Jusqu'à présent, mes solutions semblent boiteux pour moi.

(1) se lient à l'objet DOM pour la liaison est:

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

Le problème est que alors mon déclenchement besoins widget pour savoir ce que DOM bjet à un déclenchement sur:. $("#summaryobject") quel genre de défaites le but

(2) Créer un objet EventBus des voies qui lie les événements et ne permettent événements d'être liés une fois. Le problème que j'ai est pour le stockage / liant les événements que je ne peux pas suivre qui l'a créé, donc je ne peux pas désinscription si je dois .... peut-être des événements non enregistrés n'est pas nécessaire événement.

Quels modèles sont d'autres qui utilisent pour gérer des événements personnalisés?

Était-ce utile?

La solution 4

J'ai fini par le faire pour l'instant:

sous mon objet PageManager j'ai écrit cette méthode

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

Pour ma classe de widgets Je l'ai fait.

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

Pour toute instance d'un widget que vous appelez registerForEvent à des événements se lient.

Ceci est loin d'être une solution parfaite. Notre conception aura encore des fuites de mémoire dans ce que nous ne faisons pas nos objets JS désinscription. Cependant, nos objets sont écrasés chaque fois qu'ils sont chargés si le pire des cas est que chaque objet dans l'application peut être enregistrée une fois, même si elles ne sont pas utilisés.

Cependant, la liaison d'une méthode pour un événement se fixe à l'objet document qui n'est pas écrasé ou cours. Donc, ce code ne nous empêchera de reconsolidation. Nous avons encore un peu d'une configuration bâclée mais les ramifications de il devrait être réduites au minimum.

Autres conseils

Il y a deux bonnes solutions à votre problème (que je peux voir).

  1. Supprimer tous vos appels bind et les remplacer par un seul appel à ou delegate live et mettre en place un auditeur qui écoute tous des événements qui se produisent dans votre application et les routes aux endroits appropriés. (En d'autres termes, créer un contrôleur).

  2. Utilisez un EventBus qui permet des événements de désinscription ainsi que souscrit. La façon la plus simple que je l'ai vu faire avec un EventBus est Peter Michaux concours complet le 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;
};

Un exemple d'utilisation de cette seconde méthode serait:

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

Vous pouvez essayer quelques choses, comme:

  1. vos espaces de noms types d'événements. De cette façon, sans la création d'une liaison entre deux instances spécifiques de vue, vous pouvez créer une relation généralisée entre les types de vues. De ton exemple ci-dessus:

    Sommaire des données Widget A

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

    Manipulation des données Widget A

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

    Consultez la documentation ici: http://api.jquery.com/bind/

  2. Décharger les gestionnaires d'événements chaque fois un widget ou un groupe de est déchargé, avant le chargement du nouveau DOM / gestionnaires.

Avez-vous essayé d'utiliser la méthode de liaison live()?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top