30

是否有任何事件驱动架构 jQuery 插件?

第 1 步:订阅

替代文字
订阅者订阅中间的事件处理函数,并传入一个回调方法,以及他们正在监听的事件的名称......

即两个绿色订阅者将监听 p0 事件。蓝色的订阅者将监听 p1 事件。


第 2 步:p0 事件由另一个组件触发到事件处理程序

替代文字

  1. 向事件处理程序触发 p0 事件
  2. 事件处理程序通知它的订阅者该事件,调用他们在步骤 1:订阅中订阅时指定的回调方法。

请注意,蓝色订阅者没有收到通知,因为它没有监听 p0 事件。


第 3 步:p1 事件被触发到事件处理程序的一个组件

替代文字

p1 事件被另一个组件触发

和以前一样,只是现在蓝色订阅者通过其回调接收事件,而其他两个绿色订阅者没有接收到事件。

图片来自 leeand00,在 Flickr 上

我似乎找不到一个,但我的猜测是他们只是在 Javascript/jquery 中称它为别的东西

这种模式也有名称吗?因为它不仅仅是一个基本的发布者/订阅者,它必须被称为我认为的其他东西。

4

7 回答 7

48

您可能不需要插件来执行此操作。首先,DOM 本身完全是事件驱动的。您可以使用事件委托来监听根节点上的所有事件(jQuery live 使用的一种技术)。要处理可能与 DOM 无关的自定义事件,您可以使用普通的旧 JavaScript 对象来完成这项工作。我写了一篇关于在 MooTools 中只用一行代码创建一个中央事件调度程序的博客文章。

var EventBus = new Class({Implements: Events});

在 jQuery 中也很容易做到这一点。使用作为所有事件的中央代理的常规 JavaScript 对象。任何客户端对象都可以发布和订阅此对象上的事件。请参阅此相关问题

var EventManager = {
    subscribe: function(event, fn) {
        $(this).bind(event, fn);
    },
    unsubscribe: function(event, fn) {
        $(this).unbind(event, fn);
    },
    publish: function(event) {
        $(this).trigger(event);
    }
};

// Your code can publish and subscribe to events as:
EventManager.subscribe("tabClicked", function() {
    // do something
});

EventManager.publish("tabClicked");

EventManager.unsubscribe("tabClicked");

或者,如果您不关心暴露 jQuery,那么只需使用一个空对象bindtrigger直接在 jQuery 包装对象上调用和调用。

var EventManager = {};

$(EventManager).bind("tabClicked", function() {
    // do something
});

$(EventManager).trigger("tabClicked");

$(EventManager).unbind("tabClicked");

包装器只是用来隐藏底层的 jQuery 库,因此您可以稍后在需要时替换实现。

这基本上是Publish/SubscribeObserver 模式,一些很好的例子是 Cocoa 的NSNotificationCenter类, Ray Ryan 在 GWT 社区推广的EventBus模式,以及其他几个。

于 2010-06-03T20:54:03.313 回答
5

尽管不是 jQuery 插件,但 Twitter 发布了一个名为Flight的 JavaScript 框架,它允许您创建基于组件的架构,通过事件进行通信。

Flight 是来自 Twitter 的轻量级、基于组件的 JavaScript 框架。与其他基于 MVC 模式的 JavaScript 框架不同,Flight 将行为直接映射到 DOM 节点。

Flight 与请求的路由方式或您决定使用哪个模板库无关。Flight 强制执行严格的关注点分离。飞行中的组件不直接相互接触。

他们将他们的动作作为事件广播,订阅这些事件的那些组件可以根据它们采取行动。要使用 Flight,您需要 ES5-shim 和 jQuery 以及 AMD 加载器。

Flight - 来自 Twitter 的轻量级、基于组件的 JavaScript 框架

于 2013-02-06T05:58:30.733 回答
2

实际上有两个:

于 2010-06-03T15:27:59.710 回答
2

这可以作为一个轻量级的消息传递框架吗?

function MyConstructor() {
    this.MessageQueues = {};

    this.PostMessage = function (Subject) {
        var Queue = this.MessageQueues[Subject];
        if (Queue) return function() {
                                        var i = Queue.length - 1;
                                        do Queue[i]();
                                        while (i--);
                                    }
        }

    this.Listen = function (Subject, Listener) {
        var Queue = this.MessageQueues[Subject] || [];
        (this.MessageQueues[Subject] = Queue).push(Listener);
    }
}

那么你可以这样做:

var myInstance = new MyConstructor();
myInstance.Listen("some message", callback());
myInstance.Listen("some other message", anotherCallback());
myInstance.Listen("some message", yesAnotherCallback());

然后:

myInstance.PostMessage("some message");

将调度队列

于 2010-06-28T16:12:34.623 回答
2

这可以使用虚拟 jQuery 节点作为调度程序轻松完成:

var someModule = (function ($) {

    var dispatcher = $("<div>");

    function init () {
        _doSomething();
    }

    /**
        @private
    */
    function _doSomething () {
        dispatcher.triggerHandler("SOME_CUSTOM_EVENT", [{someEventProperty: 1337}]);
    }

    return {
        dispatcher: dispatcher,
        init: init
    }

}(jQuery));



var someOtherModule = (function ($) {

    function init () {
        someModule.dispatcher.bind("SOME_CUSTOM_EVENT", _handleSomeEvent)
    }

    /**
        @private
    */
    function _handleSomeEvent (e, extra) {
        console.log(extra.someEventProperty) //1337
    }

    return {
        init: init
    }

}(jQuery));

$(function () {
    someOtherModule.init();
    someModule.init();
})
于 2012-01-02T08:51:38.857 回答
2

最近的一个发展是msgs.js “面向消息的 JavaScript 编程。受 Spring 集成的启发”。它还支持通过 WebSockets 进行通信。

msgs.js 将“企业集成模式”一书中定义的词汇和模式应用于 JavaScript,将面向消息的编程扩展到浏览器和/或服务器端 JavaScript。最初开发用于集成松散耦合的不同系统的消息传递模式同样适用于单个应用程序进程中的松散耦合模块。

[...]

测试环境:

  • Node.js (0.6, 0.8)
  • 铬(稳定)
  • Firefox(稳定,ESR,应该可以在早期版本中使用)
  • 即(6-10)
  • Safari(5、6、iOS 4-6,应该可以在早期版本中使用)
  • Opera(11、12,应该可以在早期版本中使用)
于 2013-05-07T20:58:59.227 回答
1

我已将OpenAjax Hub用于其发布/订阅服务。它不是一个 jQuery 插件,而是一个独立的 JavaScript 模块。您可以从 SourceForge下载并使用参考实现。我喜欢分层主题命名和支持使用通配符符号订阅多个主题。

于 2010-06-04T02:59:20.630 回答