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:
- subscriber registers a callback with a well-known topic
- publisher delivers a message to a well-known topic
- callback will be invoked when subscriber gets a message from the topic it registered.
- To Download it from here and include pagebus.js in your page.
- To register:
window.PageBus.subscribe(topic, scope, function(sub, message, data){
.....
}, data); - To publish:
window.PageBus.publish(topic, message);
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 {copy pagebus.js to the pagebus/web-app/js/pagebus.
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
}
}
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>