我已经做了几个小时的其他研究,但是我仍然找不到一个很好的模式,因为我认为这是一个普遍的问题。

我正在开发.NET MVC2应用程序。我们的应用程序由主页组成,然后多个部分视图(随附页面)每个部分视图对应于一个由一个组成的小部件 html 结构和 JS-Jquery 胆量

我们的一些小部件彼此之间具有丰富的交互作用,因此我们当然正在使用jQuery的事件来束缚某些事物:

数据摘要小部件

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

数据操纵小部件

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

我们存在的问题是,当用户导航到应用程序的一部分时,这些小部件(HTML/dom)将从页面中删除,并替换为新的部分视图集。当用户将HTML(视觉表示)引入时,将与jQuery绑定一起重新加载,从而产生双重绑定。

到目前为止,我的解决方案对我来说似乎很la脚。

(1)与DOM对象结合绑定为:

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

问题在于,我的触发窗口小部件需要知道要触发的dom bject: $("#summaryobject") 哪种破坏了目的。

(2)创建一个事件布斯对象,向绑定哪些事件,仅允许事件绑定一次。我遇到的问题是,在存储/绑定事件时,我无法跟踪谁创建的事件,因此如果需要的话,我将无法登记。...也许未注册的事件不是必需的。

其他人使用哪些模式来管理自定义事件?

有帮助吗?

解决方案 4

我现在最终这样做:

在我的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对象。但是,我们的对象每次加载时都会被覆盖,因此更糟糕的情况是,即使不使用应用程序中的每个对象,都可以注册一次。

但是,将方法绑定到事件与未覆盖或课程的文档对象结合。因此,此代码将阻止我们重新启动。我们仍然有一些草率的设置,但是应将其分析最小化。

其他提示

您的问题有两种好的解决方案(我可以看到)。

  1. 删除所有 bind 呼叫并用单个电话代替它们 delegate 或者 live 并设置听众来听 全部 您的应用程序中发生的事件并将其路由到适当的位置。 (换句话说,创建一个控制器)。

  2. 使用允许事件取消订阅和订阅的事件总线。我看到的最简单的方法是使用Eventbus做到这一点 事件脚本.


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

使用该第二种方法的一个示例是:

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

您可以尝试几件事,例如:

  1. 命名事件类型。这样,虽然不在两个特定视图实例之间创建绑定,但您可以在视图类型之间创建广义关系。从上面的示例中:

    数据摘要小部件

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

    数据操纵小部件

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

    在此处查看文档:http://api.jquery.com/bind/

  2. 在加载新的DOM /处理程序之前,只要将事件处理程序卸载时,每当卸载了事件处理程序。

您是否尝试过使用 live() 绑定方法?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top