PDA

View Full Version : Controllers referencing other controllers!



Kikketer
7 Nov 2013, 9:03 AM
So I might get slapped by the hardcore MVC guys, but I basically had a layout that looks like this:
NavView -- Has a NavController
|- Container1 -- Has a ConController1
|- Container2 -- Has a ConController2

Now given the standard flow of a Controller listening to events from it's Views, I kind of wanted to separate the navigation logic (from container to container) away from each container's controller (ConController1 should not have to care that when it's done where to go next). Basically we need an event emitted from ConController1 to be listened for by NavController, where NavController has the logic for "hey that controller is done, I know where to go next".

Here's a breakdown of the steps:
User taps "search" on Container1
ConController1 listens for this tap and does the actual call to get the search results
When the search results have returned, fire an event "ImDone!"

NavController listens for "ImDone!" and knows that Container2 should be displayed next
This separates the logic of each container, and allows us to potentially move these containers around (with their controller) to other navs (perhaps in a different tab or the like). And it separates the NavController from having the fine details of what's inside of it, it can basically listen for the "ImDone!" on each of it's known controllers and take steps without having to do the (in this case) searching itself.

The config for the NavController looks like this:


config: {
refs: {
NavView: 'navview',
ConController1: "TestApp.controller.ConController1"
},


control: {
NavView: {
pop: 'onPop',
push: 'onPush'
},
ConController1: {
imdone: 'conOneNextPage'
}
}
},

Currently in Sencha it doesn't appear to allow controllers to reference other controllers (at least with the nice config maps we are used to). We have created an adapter to allow a controller to listen to events off of other controllers using this logic (in the NavController):


launch: function (app) {
Ext.Logger.verbose("MasterNavController launch");
var self = this;


// if any reference is undefined, try to find it as a controller
Ext.Object.each(Object.getPrototypeOf(this.getRefs()), function(referenceId) {
if(!this["get" + Ext.String.capitalize(referenceId)]) {
if(TestApp.app.getController(referenceId)) {
var controller = TestApp.app.getController(referenceId);
Ext.Object.each(Object.getPrototypeOf(self.getControl()[referenceId]), function(controlId, controlVal) {
controller.on(controlId, self[controlVal], self);
});
}
}
});
}

Now this code is more useful in a parent, to be reused by any and all other NavControllers. I realize the method uses the specific "getController" for the app, but if it could be generalized one step further, it could be a valuable addition to all controllers "Ext.app.Controller".

Let me know what you think!

keckeroo
13 Nov 2013, 10:49 AM
Hi there,

You should be able to have one controller fire your event, and the other controller should pick it up if you've configured a listener in your controller in a listener block.

eg


Ext.define('Myapp.controller.Main', {
extend: 'Ext.app.Controller',

config: {

},

listeners: {
'eventFromElsewhere': function() {
}
}

});