事件模式是界面層主要模式,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); |
事件類型eventType用來標識傳給總線消息類型,是一個重要的輸入參數,當然我們可以使用字符串來實eventType,比如"mySendEvent",但是使用一個和目標target綁定機制可能更好,如下:
Sample.EventBus.registerEventType = function registerEventType(target, eventType) { if (!target.Events) target['Events'] = {}; target.Events[eventType] = eventType; } |
使用註冊事件類型如下:
// 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'); |
我們可以使用下面代碼激活事件:
//廣播羣發事件 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 }); |
這個事件總線可以加入更多功能:日誌logging, 跟蹤tracing, 轉換translation, or 定期執行scheduled execution(切分激活動作單獨執行,異步,這樣可以避免堵塞UI線程)。
相比服務器端的事件模式,JS實現起來夠簡單。