Documentation

disgustedtukwilaInternet και Εφαρμογές Web

14 Δεκ 2013 (πριν από 3 χρόνια και 8 μήνες)

85 εμφανίσεις

Documentation


Below, you will find out how to use this plugin. It is quite powerful and will be getting more powerful with each passing
version. But even with it’s

power, it is quite simple to use. How about we just move along to the rest of the
documentation, shall we?

DEPENDENCIES

JZ Publish/Subscribe is dependent on only one thing, and that’s jQuery itself. You must be using jQuery version 1.4.3 or
higher.

$.
SUBSCRIBE()

jQuery.subscribe( topics, callback(topic, data)[, context] )

topics

A string containing the names of one or more topics to subscribe to, separated by a space.

callback(topic, data)

A function that will be executed when a topic that is subscribe
d to get published to. topic is the
topic that was published to that called this callback function. data is the data that the publisher provides.

context

Optional object that the callback function will be called on. Inside the callback the this keyword wil
l refer to this
context object.

Returns a “handle” that can be used to easily unsubscribe. You can read more about it in the General Notes.

The subscribe method is quite simple. All you need to do is give the function a topic and a callback. If the topic t
hat you
specified gets published to, the callback will be executed (in the context of an empty object or the specified context,
meaning this refers to {} or the specified context object). You may include more than one topic to subscribe the callback
to jus
t by adding a space and listing another topic. If there are multiple callbacks subscribed to one topic, they will be
executed in the order that they were subscribed. See below for example usage of $.subscribe():

// Subscribe to a single topic called 'foo'

var handle = $.subscribe("foo", function (topic, data) {


console.log(data, topic);

});


// Subscribe to multiple topics at once

// 'foo', 'bar', and 'baz' are three different topics

var handle = $.subscribe("foo bar baz", function (topic, data) {


console
.log(data, topic);

});



// Subscribe with a context

// Callback now has its this keyword assigned to the specified object

var obj = {


data: 0,


func: function (topic, data) {


console.log(data, topic, this.data);


}

}

var handle = $.subscribe("foo",
obj.func, obj);

$.UNSUBSCRIBE()

jQuery.unsubscribe( handle )

handle

The handle object gained from a previous subscribe call.

Returns jQuery

jQuery.unsubscribe( topics[, callbackReference[, context]] )

topics

A string containing the names of one or more top
ics to unsubscribe from, separated by a space.

callbackReference

The reference to a callback that was previous subscribed

context

object that was used as the context in the $.subscribe() call

Returns jQuery

$.unsubscribe is a little more difficult to expla
in due to the number of options you have. The first option allows you to
just use the handle that you received from calling $.subscribe as the only parameter. This will unsubscribe everything
that was subscribed in the call that you received the handle fro
m.

Our second option is to specify the topic(s), a reference to a callback that had been previously subscribed, and if a
context was used in the subscription you need to specify that same context as well. If you used an anonymous function
as the callback f
or the subscription, then you can retrieve a reference to the callback from the handle: handle.callback.
The topics are listed in the exact same way they are listed when you subscribe. The space character is the separator
between each topic.

The final opti
on for unsubscribing is to just include the topic(s). This will remove every single subscription to those topics
in one swoop.

As a final note: since $.unsubscribe returns the jQuery object, calls to unsubscribe can be chained together.

// Unsubscribe usin
g the handle gained from calling $.subscribe.

$.unsubscribe(handle);



// Unsubscribe by specifying the topics and callback

$.unsubscribe("foo bar", callback_reference);

// or

$.unsubscribe("foo bar", handle.callback);


// Unsubscribe exactly as above, exc
ept with context (if a context was supplied during subscribe)

$.unsubscribe("foo bar", callback_reference, context_obj);

// or

$.unsubscribe("foo bar", handle.callback, handle.context);


// Unsubscribe all callbacks from 1+ topics

$.unsubscribe("foo bar");

$.PUBLISH()

jQuery.publish( topics[, data] )

topics

A string containing the names of one or more topics to publish to, separated by a space.

data

The data to be sent to the subscriber(s)

$.publish is the function that makes the ability to subscribe useful
. Any and all callbacks subscribed to the topic(s) that
you publish to will be executed in the order they were subscribed. Optionally you may include a data parameter, which
is any variable or piece of data that you want your subscribers to have in order f
or them to do their job properly. This
can be in any format


number, string, boolean, object, function, etc


you want it to be, as long as it all fits in one
variable. See below for some example code.

// Publish to some topics without any data

$.publish(
"foo bar");


// Publish to a single topic with some data

$.publish("foo", );

GENERAL NOTES

Topics:

Topics can use any name that can also be used as a property name. Since the topic is always retrieved using the bracket
notation (e.g. object["prop"]), as op
posed to the dot notation (e.g. object.prop), you are allowed to use a large numbers
of characters that aren’t legal for variable names, such as slashes (“/”) or periods (“.”). You cannot, however, use a space
(” “) because this is the character that separ
ates multiple topics.

All three functions (subscribe, unsubscribe, and publish) are able to take one or multiple topics (separated by a space).

Handle:

The handle that is returned from the $.subscribe function is simply an object with three properties, nam
ed “topics”,
“callback”, and “context” that correspond to the three parameters that you sent in (or context will be a blank object if
no context was provided):

handle = {


topics : "the topics you sent in",


callback : function () {


// this i
s the callback function you sent in


},


context : contextObjYouSentIn or {}

};

Callback Topic Argument:

The first argument that the callback receives is the topic in which the function was subscribed and invoked from. This
will always be a string co
ntaining only one topic, even if the $.publish function is called with multiple topics because the
callback will be run once for each individual topic that is published.


If you don’t already know, JZ Publish/Subscribe is a jQuery plugin that I developed t
o 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.

What is Publish/Subscribe?

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 r
un 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 implementat
ion 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 greate
r
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.

How to Use JZ Publish/Subscribe

I’m going to show an example that u
ses 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.

We’ll start off by creating the HTML do
cument where the widget will reside. It’s quite simple. All we need within the
document is a button that refreshes the widget with the latest posts and a container for all of the tweets. Also, we can’t
forget to get the JavaScript libraries we all depend o
n.

<!DOCTYPE HTML>

<html lang="en
-
US">

<head>

<meta charset="UTF
-
8">

<title>Twitter Widget</title>

</head>

<body>

<button class="refresh
-
button">Refresh</button>

<div class="twitter
-
widget"></div>

<script type="text/javascript"
src="http://ajax.googleapis.
com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>


<script type="text/javascript" src="http://www.joezimjs.com/wp
-
content/uploads/jquery.pubsub.1.1.1.min_.js"></script>

</body>

</html>

I’d show you the CSS, but this is a JavaScript blog and you can pull
the CSS I use by viewing the source on the demo page.
Anyway, moving on. Now we’ll create a model, or an object that stores and retrieves the tweets. Here it is:


var model = ({

init: function() {

$.subscribe('update
-
tweet
-
data', this.getTweets);

return th
is;

},

getTweets: function() {

// get tweets from twitter via JSONP Ajax

$.getJSON('http://search.twitter.com/search.json?q=from:joezimjs&callback=?', function(data){

// If we got some results, assign the data to model.data, otherwise, just keep the data a
s is

model.data = data && data.results || model.data;

// Publish that we have tweets ready to be used

$.publish('tweet
-
data
-
changed', model.data);

});

},

data: []

}).init(); // Initialize the model

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 thegetTweets function when that topic is published. Notice that
inside getTweets we cannot use the keyword this in order to refer to t
he 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.


1.

var view = ({

2.


init: function() {

3.


$.subscribe('tweet
-
data
-
changed', this.displayTweets);

4.


// bind a click to the refresh button to publish 'gettweets', then
click it right away to get the first batch of
tweets.

5.


$('.refresh
-
button').on('click', '', this.refresh).trigger('click');

6.


return this;

7.


},

8.


displayTweets: function (topic, data) {

9.


var len = data.length,

10.


i = 0,

11.


// Remove
the widget from the DOM and clean it out

12.


$wgt = $('.twitter
-
widget').detach().empty();

13.



14.


// Go through each tweet and append them into the widget

15.


for(; i<len; i++){

16.


var data_i = data[i],

17.


tweeter = data_i.from_user,

18.


tweetText = data_i.text;



19.


tweetText = tweetText.replace(/http:
\
/
\
/
\
S+/g, '<a href="$&" target="_blank">$&</a>')

20.


.replace(/(@)(
\
w+)/g|>, ' $1<a href="http://twitter.com/$2" target="_blank">$2</a>')

21.


.replace(/(#)(
\
w+)/g|>, ' $1
<a href="http://search.twitter.com/search?q=%23$2" target="_blank">$2</a>');

22.



23.


$wgt.append('<div class="tweet"><a href="http://twitter.com/'+tweeter+'" target="_blank"><img
src="'+data_i.profile_image_url+'" class="tweet
-
image" /></a>'+tweetTe
xt+'</div>');

24.


}

25.


// re
-
attach the widget to the DOM

26.


$('body').append($wgt);

27.


},

28.


refresh: function() {

29.


// Publish that we want tweets

30.


$.publish('update
-
tweet
-
data');

31.


}

32.

}).init(); // Initialize the view


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.


Why We Needed JZ Publish/Subscribe


I’m sure there are some of you who wonder why on earth we bothered using the Pub/Sub patter
n 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 lat
er 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, e
ven 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 mode
l 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 ke
eping 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 organ
izing your
code and using the Pub/Sub pattern.

Wrapping Things Up

Amazingly, even when I’m writing posts that aren’t in the JavaScript Design Patterns series, I still end up writing about
design patterns. I even brought up the Observer pattern, which is ne
xt up on the list for the JavaScript Design Patterns.
The best part is that it wasn’t even intentional. Well, now you got a slight preview of the Observer patter and its
usefulness, but you still shouldn’t skip reading the post about it; there’s still plen
ty more to learn about it.

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 patte
rn 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!