Sunday, March 28, 2010

A simple PageBus taglib

Today, javascript component is a must-be part in many web applications. As more and more such components are included in the web page, the difficulty of interaction between these components is increasing. There is a way to simplify this problem: Event. With it, what you need to do is to register your callback with the event that will be fired by your interested component, and to wait for the magic happened.

All seems good, but "how to register your callback with the component you care about?" If there is a long distance between those two component, this register is not a easy work. That's why I choose PageBus as the backbone of the interaction between components in my project.

If you are familiar with jms, you can simply think pagebus as a jms implemention in the web page. Here is an intuitive picture from its document:



The biggest benefit you can acquire from PageBus is full decoupling between those two parts of interaction. One component doesn't bother another. The whole interaction process is:
  1. subscriber registers a callback with a well-known topic
  2. publisher delivers a message to a well-known topic
  3. callback will be invoked when subscriber gets a message from the topic it registered.
Usage of PageBus is very simple, you just need:
  1. To Download it from here and include pagebus.js in your page.
  2. To register:
        window.PageBus.subscribe(topic, scope, function(sub, message, data){
    .....
    }, data);
  3. To publish:
        window.PageBus.publish(topic, message);
At the end of this post, I will create a simple PageBus taglib to show how to use it.

First, let's create a new Grails App, grails create-app pagebus.

Next, enter your application directory and create a taglib, grails create-tag-lib pagebus.

In your taglib file, write down the code:

class PagebusTagLib {

static namespace= "pagebus"

static final DEFAULT_TOPIC= "app.topic.default"

def include= {
def js= """
<script type="text/javascript">
var App = {
publish: function(topic, message){
window.PageBus.publish(topic, message);
},
subscribe: function(topic, scope, fn, data){
window.PageBus.subscribe(topic, scope, fn, data);
}
}
</script>
"""
out << g.javascript(src:'pagebus/pagebus.js')<< js
}
}
copy pagebus.js to the pagebus/web-app/js/pagebus.

In the app index.gsp,

  • add <pagebus:include/> to <head> section;
  • add a button in your <body> for publishing a "hello world!" message
        <input type="button" value="publish"
    onclick="App.publish('topic1', {message: 'Hello World!'})">
  • register your callback to show the message the subscriber received.
        <g:javascript>
    App.subscribe("topic1", null, function(sub, message, data){
    alert(message.message);
    }, null);
    </g:javascript>
Finally, run your app and test it. Now, you just create your first PageBus application!