javascript事件总线

09-12-24 banq
事件模式是界面层主要模式,MVC模式中,模型组件应该和界面形成松耦合,只要界面发出事件,就应该立即响应,MVC模式也是依靠事件模式来实现彼此联系,所以,有时,我们抛开MVC模式这个锅盖,专注于事件模式,反而会有一种比较开阔的感觉。

Javascript可以避免错误类型的共享,以及避免UI界面线程,这样实现事件模式就非常简单(相对Java等语言),

[URL=http://blogs.msdn.com/simonince/archive/2009/12/21/a-javascript-event-bus.aspx]A JavaScript Event Bus[/URL]一文给出了Javascript的事件总线event bus实现案例。

使用一个Event Bus接受所有的事件,然后发布给所有的监听者:

Type.registerNamespace('Sample')
 //创建一个事件总线
Sample.EventBus = function() {
    Sample.EventBus.initializeBase(this);
}
 
Sample.EventBus.prototype = {
    //一对一激活提交事件
    subscribe: function subscribe(eventType, callback) {
        this.get_events().addHandler(eventType, callback);
    },
    //一对多广播发布事件
    publish: function publish(eventType, arg) {
        var handler = this.get_events().getHandler(eventType);
        if (handler)
            handler(arg);
    }
}
 
Sample.EventBus.registerClass('Sample.EventBus', Sys.Component);
<p>

事件类型eventType用来标识传给总线消息类型,是一个重要的输入参数,当然我们可以使用字符串来实eventType,比如"mySendEvent",但是使用一个和目标target绑定机制可能更好,如下:

Sample.EventBus.registerEventType =
   function registerEventType(target, eventType) {
    if (!target.Events)
        target['Events'] = {};
    target.Events[eventType] = eventType;
}
<p>

使用注册事件类型如下:

// simple class to carry data values with event
//创建一个带有事件数据的对象
Sample.Payload = function(dataValue) {
    this.data = dataValue;
}
 
// definition of event types relevant to Payload class
Sample.EventBus.registerEventType(Sample.Payload, 'Update');
//注册Click点按事件
Sample.EventBus.registerEventType(Sample.Payload, 'Click');
<p>

我们可以使用下面代码激活事件:

//广播群发事件
bus.publish(Sample.Payload.Events.Update, new Sample.Payload('Some Data'));
//一对一激活一个事件,类似MVC中Controller或Action
bus.subscribe(Sample.Payload.Events.Update, function(arg) {
    // perform some action
});
<p>

这个事件总线可以加入更多功能:日志logging, 跟踪tracing, 转换translation, or 定期执行scheduled execution(切分激活动作单独执行,异步,这样可以避免堵塞UI线程)。

相比服务器端的事件模式,JS实现起来够简单。

源码案例下载

8
tianqiq
2009-12-25 09:25
javascript 有最强的语言表达能力。很喜欢。哈哈。

netcasewqs
2010-04-12 12:59
事件总线在基于事件的界面层的作用是非常重要的,可以降低界面之间的藕合性,可以把界面中的事件注册到事件总线上,然后由控制器订阅事件总线上的消息,这样就把界面工程师和软件开发人员解耦出来,呵呵!

猜你喜欢