2012-10-11 71 views
2

我有2個控制器:JavascriptMVC:聽實例化控制器的事件在包裝控制器

$.Controller('App.Browse', 
/** @Static */ 
{ 
    defaults : {} 
}, 
/** @Prototype */ 
{ 
    init : function(){ 
     $('#map').app_map(); 
    }, 
    // how can I listen here for an event of app_map() controller 
}) 

$.Controller('App.Map', 
/** @Static */ 
{ 
    defaults : {} 
}, 
/** @Prototype */ 
{ 
    init : function(){ 
     // how can I trigger an event to be listened by app_browser() controller 
    }, 
}) 

短想法是,雖然我在App.Map控制器I想要注意App.Browse控制器做些什麼。

+0

有趣的問題。這引發了我的好奇心,只是做了一些研究,我確信這些會幫助你http://javascriptmvc.com/docs.html#!jquery.controller.listening和http://forum.javascriptmvc.com/主題/ how-to-bind-event-listeners-across-controllers – chridam

回答

1

JMVC準備爲了那個原因。只要聲明它是這樣的:

$.Controller('App.Browse', 
/** @Static */ 
{ 
    defaults : { 
     mapController: null 
    }, 
    listensTo: ['mapCustomEvent'] 
}, 
/** @Prototype */ 
{ 
    init : function(){ 
     $('#map').app_map(); 
    }, 

    '{mapController} mapCustomEvent': function(element, event, param) { 
     //handle event 
    } 
}) 

$.Controller('App.Map', 
/** @Static */ 
{ 
    defaults : {} 
}, 
/** @Prototype */ 
{ 
    init : function(){ 
     param = "something I'd like to pass into event listener"; 
     $(this).trigger('mapCustomEvent', params); 
    } 
}) 

和實例:

map = new App.Map('#map'); 
new App.Browse($('#browse'), {mapController: map}); 
2

你可以試試下面幾行內容:由

init : function(){ 
    events = createEventManager(["mapTrigger"]); 
}, 

,並在瀏覽器聽吧:在地圖控制器

window.createEventManager = (function() { 

var Event = function(manager, name) { 
    this.name = name; 
    this._manager = manager; 
    this._listeners = []; 
}; 

Event.prototype = { 
    listen: function(fn) { 
     if (!$.isFunction(fn)) { 
      throw "fn is not a function."; 
     } 

     this._listeners.push(fn); 
    }, 

    fire: function(args) { 
     args = args || {}; 
     args.name = this.name; 

     var ls = this._listeners; 
     for (var i = 0, l = ls.length; i < l; ++i) { 
      ls[i](args); 
     } 

     this._manager.fire(args); 
    } 
}; 


var EventManager = function(eventNames) { 
    for (var n in eventNames) { 
     this[eventNames[n]] = new Event(this, eventNames[n]); 
    } 

    this._listeners = []; 
}; 

EventManager.prototype = { 
    /** 
    * Listen to all events 
    * @param fn 
    */ 
    listen: function(fn) { 
     if (!$.isFunction(fn)) { 
      throw "fn is not a function."; 
     } 

     this._listeners.push(fn); 
    }, 

    fire: function(args) { 
     var ls = this._listeners; 
     for (var i = 0, l = ls.length; i < l; ++i) { 
      ls[i](args); 
     } 
    }, 

    getEvent: function(name){ 
     return this[name]; 
    } 
}; 

return function(eventNames) { 
    return new EventManager(eventNames); 
}; 
})(); 

$('#map').app_map().events.getEvent("mapTrigger").listen(function(){ 
     // Logic to perform on trigger. 
    }); 
+1

+1你的事件管理代碼是相當不錯的,但我認爲在組和單個級別拆分兩個數組中的偵聽器並不是一個好的結構。在取消訂閱時,您必須記住您訂閱的內容,活動或經理。而且,如果您訂閱了管理器,則僅從其中取消訂閱一個或兩個事件,而無需爲其寫入邏輯。 – maulik13

+0

有效的點,我很想聽聽你的建議,以不同的結構。 – AskeG

+0

管理器方法addListener和removeListener如何在Event對象上調用相同的方法?可以簡化接口,只需使用EventManager添加和刪除偵聽器,並在事件管理器上使用這些函數來訂閱單個或所有事件。 – maulik13

相關問題