As a part of our October Free Dojo Support initiative, we received the following question from Manu Subramanian about how to manage communication between distinct components in a rich internet application:

We are building an application with dojo. It does have many inter connected interface parts. For example it does have a top bar with drop down buttons. The menu items opens tabs in a tab controller. In general we need to call functions from different widgets or there are many interconnections between widgets. Is it good to create a widget containing the small widgets to handle these interconnections with ‘widgetsInTemplate’ property set. Is there any change coming in near future in this regard. Especially related to ‘_TemplatedMixin’. Or is there any better architecture for this?

Excellent question, Manu! This line of inquiry often arises when constructing an application with distinct UI regions which need to intercommunicate. While there is not necessarily One Right Answer, let’s explore some promising options.

First, let’s re-examine the core concern: we have an application where widgets in one region need to communicate to widgets in other regions. However, connecting directly between these widgets may prove brittle: some of them may not always exist, or perhaps parts of the application may change in the future, which would prove troublesome if components directly reference each other throughout. Therefore, an option which promotes decoupling and separation of concerns would be particularly desirable. This sounds like a textbook case for the publish/subscribe pattern, available in Dojo via dojo.publish and dojo.subscribe.

dojo.publish and dojo.subscribe implement the idea of a central hub, which can receive messages on given topics (sent by calls to dojo.publish). Interested parties can request notification of messages on particular topics by calling dojo.subscribe, passing a callback which will be invoked any time dojo.publish is called for that topic. The important thing to note is that no publisher or subscriber necessarily knows anything about who else is publishing or subscribing to the same topic within the application, so there is no tight coupling or context-sensitivity inherent in the paradigm.

Now that we understand the notion of pub/sub, how do we really apply it to our application? Where exactly should the publishes and subscriptions happen?

With regard to publishing to topics, clearly this could be done on an atomic per-widget basis, but that could prove onerous. In certain cases, it may be possible to build simple extensions to simplify matters considerably. Take menus, for example: it would be wasteful to have to hook up a onClick handler for each item, but we can easily build it into a menu extension of our own. Here is a trivial example to get started:

dojo.provide("my.PubMenu");
dojo.declare("my.PubMenu", dijit.Menu, {
    onItemClick: function(item, evt){
        this.inherited(arguments);
        // don't forget that dojo.publish takes an array of arguments
        dojo.publish("/my/pubmenu/click", [item.id]);
    }
});

This code defines a very simple module which will publish an event every time an item is clicked within an instance of this menu widget. Here’s a simple example of how we could put it to the test:

// create a menu instance
var menu = new my.PubMenu({
    id: "menu1"
});
// generate some menu items
for (var i = 1; i <= 5; i++) {
    menu.addChild(new dijit.MenuItem({
        id: "item" + i,
        label: "Item " + i
    }));
}
// place or hook up where desired within application layout
menu.placeAt(dojo.body());
menu.startup();

// for testing purposes: alert the id of the clicked item
dojo.subscribe("/my/pubmenu/click", function(id){
    alert("menu item clicked: " + id);
});

A pattern like this could similarly be followed for other widgets with homogenous children, such as toolbar buttons, and perhaps even tree nodes.

The next question is where best to hook up subscriptions; again, there are multiple options. It may be possible to find appropriate places to add subscriptions directly within the logic of widgets in the application, particularly if each region is governed by a custom “top-level” widget. On the other hand, at large scale this could make it difficult for someone coming back to the code later to figure out where particular topics take effect, and it might also complicate maintenance if significant or constant redesigns are expected.

A potential alternative would be to set up a sort of controller object to take care of hooking up subscriptions. This need not be a full-blown dojo.declared class, although if you want to take the idea of a controller a step further and also apply it to individual regions, that could be an option as well.

The idea of a controller also presents a potential alternative to the publish/subscribe pattern: instead, you can choose to hook up everything through the controller. There is a great tutorial on this topic, which may give you some interesting ideas to get started. You may also be interested in this tutorial, which focuses on different options for managing events, connections, and pub/sub.

Moving on to address your inquiries regarding templated widgets, there are certainly cases that could be made for either templated or fully-programmatic composition of widgets within regions of the UI. Templated widgets tend to lend themselves best to cases where there is a distinct and finite set of child widgets involved. In the case of toolbars, menus, and layout widgets in a large application, it’s quite possible that the children present will need to depend on some configuration or other external factors, and cannot be predefined; this case would favor a programmatic approach.

For example, in the previously-linked controller tutorial, you may have noticed that there are really no custom templated widgets involved; the general layout of the UI is defined directly in the main page of the application, and child widgets (e.g. new tabs) are created programmatically within the controller.

Regarding future changes, in Dojo 1.7 dijit/_Templated is deprecated in favor of the new individual mixins dijit/_TemplatedMixin and dijit/_WidgetsInTemplateMixin. This makes it possible to reduce overhead in cases of widgets which can benefit from templating, but do not need to parse child widgets within that template. When interested in templating with child widgets, you would include both of these mixins.

We hope the ideas presented above have started your thoughts flowing. Best of luck in developing your rich internet application!

SitePen Support

Sign-up for the Best JavaScript and Dojo Support available to get all of your questions answered all the time!