Continuing from last week, where I introduced a simple but powerful Dojo MVC solution, let’s look at how to put it together into a simple but useful application “framework”.
Adding controller switching
What would be an application without a way to change controllers and views? An iPhone (pre OS 4?)!
Luckily for us, we can do this pretty easily, just like the controller and view.
We will just use dojo’s event publishing for this, as it’s a straightforward way, and if we want we can easily hook other things to the same events if necessary.
dojo.subscribe('/controller/change', function(name, parameters) { var fullname = name + 'Controller'; dojo.require('CU.' + fullname); var controller = new CU[fullname](); controller.startup(); controller.placeAt(document.body, 'only'); controller.activate(parameters); }); |
Here’s a simple controller switching event listener. As you may recall, the controllers were called CU.SomethingController in the previous post, so we first need to require the controller class to be sure it’s actually available.
Next, we instanciate and start the controller. We need to remember to call startup, because the controller is a dijit. If you’re using the two-part controller/view thing where the view is the dijit and the controller is just a normal class, remember to call startup on the view. I trip on dijits and startup very often because I keep forgetting it myself.
Finally, we put the controller in the document.body as the only node and call the activate method.
This is basically all we need for our simple case. To kickstart our application, we simply do:
dojo.publish('/controller/change', ['Foo', { parameter1: 'foo', arg2: 'bar' }]); |
Which would change to controller FooController and call the activate function with the object with parameter1 and arg2.
When you wish to change to any other controller, using the same publish call will work.
Polishing it a bit
You may also recall that in the previous post, we had a deactivate function. Where is that in our controller switching code?
Let’s add it:
var activeController = null; dojo.subscribe('/controller/change', function(name, parameters) { if(activeController) { activeController.deactivate(); } var fullname = name + 'Controller'; dojo.require('CU.' + fullname); var controller = new CU[fullname](); controller.startup(); controller.placeAt(document.body, 'only'); controller.activate(parameters); activeController = controller; }); |
Now it’s almost perfect. What about if you want to be able to add your dependencies to your controller, to make them easier to test?
var activeController = null; var controllers = { }; dojo.subscribe('/controller/change', function(name, parameters) { if(activeController) { activeController.deactivate(); } var fullname = name + 'Controller'; var controller = controllers[fullname]; if(!controller) { dojo.require('CU.' + fullname); controller = new CU[fullname](); controller.startup(); controllers[fullname] = controller; } controller.placeAt(document.body, 'only'); controller.activate(parameters); activeController = controller; }); |
Now we have an object to keep track of already created controllers. If one of them has dependencies, we could manually create the controller, and the code would pick our already instanciated one from the object.
Conclusion
You don’t need a huge amount of code to be able to create an application with architecture that allows for not only easy development but also testability.