PDA

View Full Version : Listen to the event fired by non component object (not Ext.Component)



jastako
13 Dec 2012, 8:11 AM
So for the last 3 days I've been struggling with an idea of handling event fired by non component class (Globals.coffee), which basically inherits directly from Ext.Base rather than from Ext.Component. As a result it lacks 'id' property, so makes it infeasible using Ext.ComponentQuery. I also asked this yesterday on SO (http://stackoverflow.com/questions/13852115/listen-to-the-event-fired-by-non-component-class-not-ext-component), but unfortunately without any response and I'm bit in rush with project.

I've only found this related solution: How to listen to a event fired by a controller in controller with Sencha Touch2 (http://stackoverflow.com/questions/10563780/how-to-listen-to-a-event-fired-by-a-controller-in-controller-with-sencha-touch2#comment-13676031) by @ThiemNguyen, who advices: "if you just want to call a specific function of that controller directly, do this:

Ext.getApplication().getController('your_controller_name').my_event_handler()
"
which in ST2.1 is equivalent to:

MyApp.app.getController('your_controller_name').my_event_handler()
, but doesn't matter.
What counts is fact, that @ThiemNguyen's proposed solution breaks encapsulation boundaries of my app. Instead of calling controller's method (Search#onDatabaseReady()) in object, which produces event (Globals), I'd rather listen for this event and handle it in mentioned controller.

My code looks like follows:

Globals.coffee:



Ext.define 'MyApp.utils.Globals',
extend: 'Ext.mixin.Observable'
singleton: true

config:
db: null

updateDb: (newDb, oldDb) ->
console.log Ext.getDisplayName(arguments.callee)
@fireEvent 'databaseReady'


Search.coffee:


Ext.define 'MyApp.controller.Search',
extend: 'Ext.app.Controller'

config:
refs:
globals: 'MyApp.utils.Globals'
control:
globals:
databaseReady: 'onDatabaseReady'

onDatabaseReady: ->
console.log Ext.getDisplayName(arguments.callee)


The only solution I have found is to introduce 3rd object, which selected variable (lets say 'databaseReset') would be changed from within Globals#onDatabaseReady(). Then its update method (updateDatabaseReset()) would access controller method Search#onDatabaseReady(). But again. It's more like workaround and still breaks encapsulation boundaries, but at least not that much as before.

Thanks in advance for any help.

Cheers,
~jastako

mitchellsimoens
15 Dec 2012, 7:14 AM
I just fire on the Application class and have controllers listen for events on the Application in the init method, the app is the only argument in the init method.

jastako
15 Dec 2012, 10:40 AM
But anyway, both controllers and application instance are still Ext.Controllers, which can't be queried.
I'm aware of addListener method, but it seems only to with child items of container or component itself.
Can you please provide some snippets?

mitchellsimoens
15 Dec 2012, 2:31 PM
In a controller:


init : function(app) {
var me = this;

app.on({
scope : me,
customevent1 : me.onCustomEvent1,
customevent2 : me.onCustomEvent2
});
}

Just fire an event on the app


MyApp.app.fireEvent('customevent1', this);

jastako
15 Dec 2012, 3:35 PM
Thanks a lot! This is what, I was looking for and indeed, it looks simple just as you described it. Thanks again!