Justin Chmura
Blarg

Dojo Widget Lifecycle

By on

Dojo ToolkitWidgets are the basis on which a vast majority of the Dojo Toolkit is based on. If you’re not familiar with Dojo, I would suggest just checking it out then coming back to this post. It’s probably overkill in what it provides for most web apps, but if you’re looking for all-in-one solution, Dojo brings quite a bit to the table.

As I’ve mentioned ESRI JavaScript API to create maps in the browser. They’ve built the API on top of Dojo so knowing how to create and manage custom widgets was key.

I wanted to make this post as a starting point going forward since I want to share some widgets I’ve written and worked with.

What is a Dojo Widget?

To put it in simple terms, a Dojo widget is basically a jQuery plugin. If you don’t know what a jQuery plugin is, then think of it as a class that can do a number of things. It’s a piece of common functionality that can do a number of things, including rendering a template out to the client. Widget behavior can be inherited from, extended, or modified.

The widget lifecycle gives you hooks in the construction and destruction of a widget where you can do things like hooking up events to a template, initializing arrays, or creating child widgets.

This is what the basic skeleton of a widget looks like:

define(['dojo/_base/declare', 'dijit/_WidgetBase'], function (declare, _WidgetBase) {
  return declare([_WidgetBase], {

    constructor: function () {
    },

    postMixInProperties: function () {
    },

    buildRendering: function () {
    },

    postCreate: function () {
    },

    startup: function () {
    },

    destroy: function () {
    }

  });
});

There’s a lot going on there that may seem confusing if you aren’t familiar with development using Dojo.

Dojo uses AMD to load and define modules, hence the define syntax. The declare module is telling Dojo that this piece of functionality should be treated as a class definition. The first parameter of the declare function is used to specify any widgets to inherit from. In this case, I’m inheriting from _WidgetBase. That’s the key to adding, what I’m going to elaborating on, the lifecycle to the custom widget.

The Dojo Widget Lifecycle

Here’s the list of key events in order as they happen:

  • constructor
  • postMixInProperties
  • buildRendering
  • postCreate
  • startup
  • destroy

The last event, destroy happens after the life of the widget has ended. The other five happen during the creation. destroy also has a handful of automatic events that fire during its deconstruction process. Those I’ll leave out as most of the time they won’t need to be hooked into, but they are there if needed.

I want to touch on the two straightforward ones first, constructor and startup . The constructor does exactly what it sounds like it does. It happens as soon as an instance of the widget is created. This should be used for any basic initialization like creating arrays, setting default values, etc.

startup is not called automatically, instead it is the last step in the initialization and called manually in your app. This allows you to do any further initialization after all child widgets have been setup and any templates have been added to the DOM.

postMixinProperties gets called just before the widget gets rendered or any elements are added to the DOM. This includes any child widgets inside this widget’s template.

Lastly, postCreate is probably where you’ll want to do most of the work. This is fired after all the properties have been initialized and setup, and the template has been created, but before it has been added to the DOM, which is the important distinction. It’s your last chance, as the developer, to make any modifications before the user sees the widget in the browser. Most of the initialization work probably belongs in this method.

Just to reiterate:

constructor -> postMixinProperties -> postCreate -> startup

Going Further

There’s a handful of additional events that happen in between some of these, but the difference between them is so minute that if you need to hook into them, it’s for a specific reason. There’s also other modules that may add additional events to the list. The documentation should state where it the list it goes.