Autowiring components to a message bus in Javascript
When writing AJAX and SOFEA/SOUI applications, it’s a best practice to use a client side message bus to integrate UI components. People recognized this as a best practice lately for GUI development with Swing. As a sidenote Werx was excellent for this but sadly is dead.
One of the ways to do message buses in Javascript is the OpenAjax Hub implementation or TIBCO PageBus.
Subscribing to messages on the bus is easy with the subscribe method:
jo.ListComponent = function() {
OpenAjax.hub.subscribe("list.get") {
function(event, publisherData, subscriberData) {
// do something when message arrives
}
}
When you have lots of those subscriptions though, they clutter up your code. Werx had the nice idea to autowire methods to messages and use the methods as message handlers. I thought I should do the same for Javascript and OpenAjax Hub.
jo.ListComponent = function() {
this.$list_get = function(list) {
// do something with list
}
// connect the methods
jo.connect(this);
}
Some magic happens in the connect method.
jo.connect = function(object) {
for (var element in object) {
if (element.charAt(0) == '$') {
var event = element.substring(1).replace(/_/g, ".");
var callback;
// we need to capture the scope
(function() {
var fn = object[element];
callback = function(event, data) {
fn.apply(object, [data]);
}
})();
jo.Bus.subscribe(event, callback);
}
}
}
The same could be achieved with a map of message handlers which is easy with functions in Javascript whereas in Java it takes more boiler code. A solution with methods as messages handlers as seen above has the benefit though that the object can contain other helper methods and state, which a map of message handlers can not. Using autowired methods makes your message bus code cleaner and more readable.
Thanks for listening.
We had considered some form of auto-wiring in the OAA hub, but it’s too magical and it’s slow. As your example shows, you can easily add it on top of what’s there, but the speed of iteration and string manipulation on slow JS engines (IE 6 and 7 in particular) makes it relatively infeasible. Even implementing hierarchal dispatch in the OAA hub was somewhat controversial for similar performance reasons.
Also, what happens when you call connect() a second time? For a script that will get passed around the net billions of times a day we decided to be somewhat hands-off about this (as I also had done in the even-simpler Dojo pub/sub system).
There will be an update to the hub at some point and you can help us define what should be in it by joining OAA or the hub mailing lists.
Regards
April 27th, 2008