The Dojo Publish/Subscribe Event Mechanism | WebReference

The Dojo Publish/Subscribe Event Mechanism

By Rob Gravelle


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:

dojo.publish(topic: String, [args: Array]);

  • 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