简单事件聚合器

3
我正在寻找一个能够与require.js一起使用的简单事件聚合器。我有两个模块,一个包含视图模型,另一个包含某种类型的“监听器”:
// view model
define(['lib/knockout-2.2.1', 'events/aggregator'], function(ko, events){

    var squareViewModel = function(contents) {
        this.click = function(){
            events.publish('squareClicked', this);
        };
    };

    return squareViewModel;
});

// some listener of some kind
define(['events/aggregator'], function(events){
    events.subscribe('squareClicked', function(e){
        alert("hurrah for events");
    });
});

有没有任何东西可以做到这一点?这种架构是个好主意吗?这是我第一次涉足客户端架构。
2个回答

4
这类似于您发布的内容,但我扩展了Backbone事件(实际上您不必使用Backbone的其他任何内容也可以实现此操作),类似于以下内容:
define(['underscore', 'backbone'], function( _, Backbone ) {
    var _events = _.extend({}, Backbone.Events);
    return _events;
});

然后你的所有视图模型(或任何代码)都可以使用它:

define(['knockout', 'myeventbus'], function(ko, eventBus){

    return function viewModel() {
        eventBus.on('someeventname', function(newValue) { 
        // do something
        });

        this.someKOevent = function() {
            eventBus.trigger('someotherevent', 'some data');
        };

    };
});

这个想法起源于Derick Bailey的这篇文章。我最喜欢的客户端事件之一是Jim Cowart的这篇文章
再次说明,这与你发布的内容基本相同。然而,我不喜欢将其绑定到jQuery文档DOM节点的方法,因为您可能有其他类型的事件从子节点冒泡出来等。而通过扩展backbone事件,您可以拥有自己专用的事件总线(甚至更多,如果您例如想要分别处理数据事件和UI事件)。
关于此示例中的RequireJS:Backbone和Underscore不支持AMD,因此您需要使用shim配置来加载它们。

这就是我最终所做的,但是 Backbone.events 应该改为 Backbone.Events。显然不能只编辑一个字符。 - sennett

1
我最终使用jQuery制作了自己的:

define([], function(){
    return {

        publish: function (type, params){
            $(document.body).trigger(type, params);
        },

        subscribe: function(type, data, callback){
            $(document.body).bind(type, data, callback);
        },
    };
});

它对我想要的功能起作用,但尚未经过广泛测试。
正如 explunit 在他的 回答 中指出的那样,这将捕获 document.body 上的任何事件。我还发现在传递的回调函数中访问 this 时存在作用域问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接