管理jQuery自定义事件

管理jQuery自定义事件,jquery,asp.net-mvc-2,custom-binding,event-bus,Jquery,Asp.net Mvc 2,Custom Binding,Event Bus,我已经做了几个小时的额外研究,但我仍然找不到一个好的模式,我认为这是一个常见的问题 我正在开发一个.NETMVC2应用程序。我们的应用程序由一个主页和多个部分视图(包括页面)组成,每个部分视图对应一个小部件,由HTML结构和jsjqueryguts组成 我们的一些小部件彼此之间有丰富的交互,因此我们当然使用jQuery的事件绑定,其效果如下: 数据摘要小部件 $(document).bind("DataUpdated", summaryobject.updateTotals()); 数据操作小

我已经做了几个小时的额外研究,但我仍然找不到一个好的模式,我认为这是一个常见的问题

我正在开发一个.NETMVC2应用程序。我们的应用程序由一个主页和多个部分视图(包括页面)组成,每个部分视图对应一个小部件,由HTML结构和jsjqueryguts组成

我们的一些小部件彼此之间有丰富的交互,因此我们当然使用jQuery的事件绑定,其效果如下:

数据摘要小部件

$(document).bind("DataUpdated", summaryobject.updateTotals());
数据操作小部件

$(document).trigger("DataUpdated");
我们面临的问题是,当用户导航到部分应用程序时,这些小部件(HTML/DOM)将从页面中删除,并替换为新的部分视图集。当用户向后导航时,HTML(可视表示)将与创建双重绑定的jQuery绑定一起重新加载

到目前为止,我的解决方案在我看来是站不住脚的

(1) 绑定到绑定的DOM对象:

$("#summaryobject").bind("DataUpdated", summaryobject.updateTotals());
这样做的问题是,我的触发小部件需要知道要在哪个DOM对象上触发:
$(“#summaryobject”)
哪种类型的触发会破坏目的

(2) 创建一个EventBus对象来绑定哪些事件,并且只允许绑定一次事件。我遇到的问题是,在存储/绑定事件时,我无法跟踪是谁创建了它,因此如果需要,我无法注销它……也许未注册的事件不是事件所必需的


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

有两种很好的解决方案(我可以看到)

  • 删除所有
    bind
    调用,并将其替换为对或的单个调用,并设置侦听器,侦听应用程序中发生的all事件,并将它们路由到适当的位置。(换句话说,创建一个控制器)

  • 使用允许取消订阅和订阅事件的EventBus。我见过的最简单的使用EventBus的方法是Peter Michaux的


  • 使用第二种方法的示例如下:

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

    您可以尝试以下几种方法:

  • 为事件类型命名空间。 这样做,而不是 在两个应用程序之间创建绑定 特定视图实例,您可以 建立一种广义关系 在不同类型的视图之间。从你的 上面的例子:

    数据摘要小部件A

    $(document).bind("DataUpdated.Statistics", summaryobject.updateTotals());
    
    数据操作小部件A

    $(document).trigger("DataUpdated.Statistics");
    
    请查看此处的文档:

  • 卸载事件处理程序 每当一个小部件或一组小部件 在加载之前卸载 新的DOM/处理程序


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

    我现在就这样做了:

    在我的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);
            }
        }
    }
    
    函数页面管理器(){
    this.eventBusRegistry=[];
    ///如果尚未绑定,则注册事件
    this.registerForEvent=函数(eventName、eventOwner、functionToBind){
    if(this.eventBusRegistry[eventName+eventOwner]==null){
    this.eventBusRegistry[eventName+eventOwner]=“绑定”;
    $(document).bind(eventName,functionToBind);
    }
    }
    }
    
    对于我的widgets类,我做了这个

       ///<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);
        };
    
    ///Widget
    函数小部件(inWidgetName){
    //您希望更新的数据。
    this.data={};
    //小部件的名称
    this.widgetName=inWidgetName;
    }
    Widget.prototype.registerForEvent=函数(eventName,functiontoBind){
    //会话是PageManager的实例
    registerForEvent(eventName、this.widgetName、functiontoBind);
    };
    
    对于调用registerForEvent绑定事件的小部件的任何实例

    这远不是一个完美的解决方案。我们的设计仍然存在内存泄漏,因为我们没有注销JS对象。然而,我们的对象在每次加载时都会被覆盖,所以更糟糕的情况是,应用程序中的每个对象都可以注册一次,即使它们没有被使用


    但是,将方法绑定到事件会绑定到文档对象,而文档对象不会被覆盖或更改。所以这个代码会阻止我们重新绑定。我们仍然有一点草率的设置,但是它的影响应该最小化。

    Live看起来很酷,但是从我最初的观察来看,它似乎非常适合非定制活动。但是,我的客户事件绑定到保持注册的JS对象。很抱歉,我没有发布最后的评论。但无论如何,我只是想详细说明一下。live无法解决问题,但我认为这可能是一种比绑定更好的方法。触发小部件仍然需要调用“DataUpdated.Statistics”,这与绑定到特定DOM对象一样,将两者紧密耦合。因此,这基本上只是使用jQuery绑定来调用事件管理器?事件管理器本身是jQuery内置事件绑定的更复杂版本?我还不太了解fire方法,但我想我知道它在做什么。@Chris--option#2实际上完全独立于任何javascript库。它创建了一个事件的中央注册表,并允许任何知道它的人为事件添加“侦听器”。无论何时调用
    fire
    ,它都会检查注册表(
    EventManager.events
    )是否包含预期名称的项。如果是的话,它会在数组上运行并调用事件数组中的每个函数。哦,我现在看得更清楚了。我实际上不知道这是如何解决双重绑定的问题的。这基本上只是重新创建Jquery事件总线。jQuery通过绑定/取消绑定提供了相同的功能。我也没有看到定制绑定的live的好处。我看到了一个好处,但不是解决这个问题的办法。我认为我的问题实际上是应用程序如何工作的总体设计。我们需要更智能地加载JS对象和进行绑定。我有一个临时的解决办法
       ///<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);
        };