There are several ways to tap into the event model in Dojo. For simple events,
you can assign a function to execute using dojo.connect
. Another way is to create
topics using dojo.publish
, which act as a queue that other objects can publish
objects to. Finally, there's Ben Nolan's behavior JavaScript library, dojo.behavior
,
which harnesses the power of dojo.query()
. With all these choices, you
could be forgiven for not knowing which to use for which purpose. Well wonder
no more! This is where we sort through confusion and work out exactly which
module to use for different circumstances. Each has a specific purpose; together
they cover the gamut of event-related tasks. My last article, Event
Listening Made Easy with Dojo.connect, explained how to bind function code
to events using the dojo.connect
module. Today, I'll be talking about dojo.publish
.
dojo.publish
versus dojo.connect
Whereas dojo.connect
provides a kind of direct action/reaction style of communication,
the publish/subscribe model is best to use in loosely coupled architectures
in which it's not prudent for objects or widgets to know about one another's
existence. Hence, it's more of a broadcast system where objects communicate
anonymously. It's especially useful where the event producing object and its
audience have a one-to-many relationship. In those situations, rather than set
up and manage multiple connections, it's a lot easier to just publish the event
and provide all the necessary information so that interested parties, called
subscribers, can take whatever action they need to in response to said action.
publish()
and subscribe()
Syntax
Publishing an event is quite easy. All you need to provide is the topic
and an optional data array for the subscribers. Also referred to as the "channel",
the topic is a string identifier for that publishing stream. Just as TV and
radio stations all have their own channel names, your published events must
also have a unique moniker. The data array can contain just about anything, so
long as the arguments are contained within an array. With this in mind, be mindful
that a single string won't work. On the other hand, a string within square brackets such
as ["I am a string"]
will work just fine. Here is the syntax:
- topic:(String) The name of the topic to publish.
- args: (Array) Optional. An array of arguments. The arguments will be applied to each topic subscriber (as first class parameters, via apply).
The dojo.subscribe()
method syntax is as follows:
var handle = dojo.subscribe(topic: String, context: Object|null, method: String|Function);
- topic:(String) The name of the topic to publish.
- context: (Object) Optional. Scope in which method will be invoked.
- method: (String|Function) The name of a function in context, or a function reference. This is the function that is invoked when topic is published.
Here's a simple example that illustrates a simple usage of the publish()
and
subscribe()
methods using the model of a newspaper publisher. The publisher
is sending out several news items contained within an object literal. It is
itself enclosed within an array literal using square braces notation ([]
). The
news items could have been passed directly to the publish()
function as individual
elements, but housing them in an object provides the advantage that each news
item can have their own identifier or title. Then on the subscriber side, an
anonymous function is used to iterate through each news item and print its name
and contents to the console:
The above code prints the following in the console window:
I got: item: news item one
another: news item 2
yetAnother: news item 3
Publishing and Subscribing Between Objects
The subscribe's optional context
argument comes in handy when the subscriber
is an object. Passing the this
pointer as the context
preserves it as the method
context and provides it with access to the object's properties and methods.
In the following example, the a publisher of lotto numbers sends out a message
over the "lotto numbers" topic whose arguments array contains an object
with two properties called numbers
and bonus numbers
.
The subscribing object formats the content using labels that are defined as member
attributes that are accessed using this.
notation:
The above code prints out the following text which contains the two label attributes:
Today's lotto numbers are 12,15,24,28,34,58
The bonus number is 22