If you don’t already know, JZ Publish/Subscribe is a jQuery plugin that I developed to add a simple, but powerful Pub/Sub feature to the jQuery utility functions. I’m guessing there are some people out there who don’t understand what Pub/Sub is, how to use it, or why to use it. I’m here to bring some answers and give a specific example of how JZ Publish/Subscribe can be used.
The first thing that should be done is help you understand what the Pub/Sub pattern really is and how it works. If you already know what the Observer pattern is (or already know what Pub/Sub is, for that matter) then you know what Pub/Sub is all about and you can move on to the next section. Both of these patterns allow you to observe/subscribe to certain events. When the event happens (or get published), then some code that you specified is run in response to that event. It really is that simple. If you’ve ever used event listeners on HTML elements before, then you have already used this pattern.
The biggest difference between event listeners or the standard observer pattern and my implementation of Pub/Sub is that my subscriptions listen for a _global _event, whereas the event listeners are added directly to the DOM elements and listen only for events for that object. There are pros and cons to each approach. The global Pub/Sub allows for greater decoupling, whereas the normal event listener makes it clearer as to exactly what events we’re listening for and won’t cause problems caused by two different events having the same name.
I’m going to show an example that uses JZ Publish/Subscribe in order to answer both of the questions at the same time. This example will be a simple widget that display the latest Twitter posts from my Twitter account.
You can view the live demo here. Demo Page has been removed due to Twitter API changes. Code samples below will also be out of date.
Now we’ll create a model, or an object that stores and retrieves the tweets. Here it is:
Here we get to see our first bits of Pub/Sub. In the
init function we subscribe to the “update-tweet-data” topic (for this plugin, events are called topics) and telling it to call the
getTweets function when that topic is published. Notice that inside
getTweets we cannot use the keyword
this in order to refer to the
model object, because the plugin calls the function in a different context. I realize that for many people this can be a nuisance, and it has already proven to be a nuisance to me, so in the next version of JZ Publish/Subscribe I will add the ability to pass in a context to run the function from.
Now if you look inside the callback for the AJAX request you’ll see a
$.publish call. This informs anyone subscribed to that topic that the model now has new tweet data so they can respond accordingly. The view is the object that will respond, and it is also the next bit of code to show.
Once again we set up our subscriptions in the
init function. Notice the next line though. We set up an
onclick handler for the refresh button that just publishes the ‘update-tweet-data’ topic, which is what the model is subscribed to. Here’s the fun part, we also immediately trigger a click event on the button in order to get the initial tweets.
The next method is
displayTweets, which is called when the model publishes the ‘tweet-data-changed’ topic right after it has finished retrieving the tweets. As you might expect by the name, this function uses the data to create the HTML to display all of the tweets in the widget container.
I’m sure there are some of you who wonder why on earth we bothered using the Pub/Sub pattern at all in this example. I agree that if you knew with 100% certainty that this is the only code you needed and weren’t going to add to it at all, then it was maybe only slightly useful for organization’s sake, however, the time this tends to shine is later when you want make some additions.
Let’s pretend that this widget is in your sidebar, but now you also want to make a page that features your twitter posts. Instead of writing an entirely new model and view, we only need a new view. For the new view, we can just remove the refresh button’s click handler and the
refresh method (which I only put in there as a method instead of an anonymous function for testing purposes), then change whatever we want to change with the DOM and HTML related code.
Normally, even if we did just add a new view, without the Pub/Sub pattern involved, you would need to update the model to also call the
displayTweets function for the new view, which would then break on any page that didn’t have the new view, unless you made the model observable, which would require a bit of work.
Using Pub/Sub decouples the model and view from each other. The view has no idea the model exists and vice versa, which makes for better scaling, as I explained above. The Pub/Sub pattern is very nice for keeping code organized and decoupled for large applications or even just for applications that might grow. If you’re going to be doing things like this a lot with large applications, I’d actually recommend Backbone.js, which gives a great framework for organizing your code and using the Pub/Sub pattern.
I hope that this has given you a bit of an overview of how to use JZ Publish/Subscribe and also made you consider using it if you haven’t already. Even if you don’t use my plugin, I hope you learned the value of the Pub/Sub pattern and use it to your advantage. Seriously, I’d rather have everyone writing better code than using my plugin. As always, feel free to leave comments or share this with your friends and Happy Coding!