Declarative vs Programatic
by Peter Higgins

The Dijit widget system expands on “Core Dojo” by providing rich, accessible and internationalized reusable components. Dojo has always had a custom declarative way of turning vanilla DOM nodes into complex widgets, but this is entirely optional, and likely faster to avoid.

There are two ways to create instances of Classes in Dojo/Dijit: Declarative and Programatic. They behave identically, though are entirely opposite approaches. For instance: to create a Dialog programatically:

   // the nodeId is not required, a node will be made for you if omitted.
   // just have to placeAt() the widget in the DOM somewhere yourself.
   new dijit.Dialog({ title:"My Dialog" }, "someNodeId");

… and the declarative equivalent:

  <div id="someNodeId" title="My Dialog" dojoType="dijit.Dialog"></div>

Both require you to setup Dojo the same way:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
 
	<title>Sample Dojo / Dijit Page</title>
 
	<!-- a Dijit theme: -->
	<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.3/dijit/themes/tundra/tundra.css" />
	<!-- load Dojo -->
	<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js"></script>
 
	<script type="text/javascript">
		dojo.require("dijit.Dialog");
	</script>
</head>
<body class="tundra"></body>
</html>

The declarative way actually requires the loading of the parser module, as it is not the default behavior to allow “invalid markup”:

dojo.require("dojo.parser");
dojo.addOnLoad(function(){
      dojo.parser.parse(); // or set djConfig.parseOnLoad = true
});

The only component in Dojo/Dijit/DojoX that is “dojoType”-aware (dojoType is the custom attribute decorated on DOM nodes to identify the Class they should be turned into) is the dojo.parser … Without the dojo.parser, the dojoType is simply a useless “invalid attribute*” which will be ignored by all browsers. With the dojo.parser, these nodes will be automatically converted into the rich components expected.

Anything that can be created with a dojoType can be created with pure JavaScript using the ‘new’ function. Rather than actually carry on about how to do it, I’ve prepared two identical pages. The programatic version would likely pass W3C validation if the <script> content were extracted into an external file or wrapped in CDATA tags, but that is not the exercise here.

Dijit 1.3 Layouts:

  • Programatic Complex Layout
  • Declarative Complex Layout

The setup of either page is identical, and mirrors the sample above: provide a theme css file, link to dojo.js (dojo.xd.js in the cross-domain case), a script area for code, and a body class=’tundra’ to enable the theme.

The difference comes in the creation. The programatic example has a “buildUI” function, which is called by dojo.addOnLoad. The declarative example replaces the buildUI function with a call to dojo.parser.parse(). The buildUI function systematically builds up the layout creating nodes along the way. The declarative example uses the nodes in the DOM already and converts them. The mapping is 1:1.

By using the programatic way, we a) eliminate validation warnings b) speed things up a bit by avoiding DOM querying and c) avoid having unrendered content on the screen when the page loads. Big wins all around!

I personally prefer the programatic way, though having the optional dojoType attribute makes prototyping my code/widgets/layout much faster — and that’s what it is all about — developer ease. It is very easy to switch working code between declarative and programatic styles.

* though I still maintain the validater is “broken”. The spec states unidentified attributes are to be ignored by the browser, and — oddly — all of them do, though the W3C validater does not respect this rule.

Tags: , ,

This entry was posted on Wednesday, April 15th, 2009 at 2:49 pm and is filed under Dojo Cookies. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

11 Responses to “Declarative vs Programatic”

  1. Uxebu.com - JavaScript addicts » Dojo - Declarative vs Programatic Says:

    [...] Dojo - Declarative vs Programatic [...]

  2. cs44 Says:

    Once again, IMO “developer ease” takes the driver’s seat here. Still, I’d like to know the difference in performance, which I’d consider a concern. However, I’m more than willing to ignore the W3C validator “errors”…

  3. unscriptable Says:

    When creating a UI that “gracefully degrades”, declarative has some advantages. However, if the rendering of the dijits needs server-side resources that can only be fetched using xhr requests, you’ve got no other choice but to use programmatic. I just hit that situation yesterday!

    Btw, great writeup, phiggins!

  4. maddesa Says:

    For any Ruby on Rails fans out there, dojo’s declarative model works incredibly well with the rails helper tags. If want to quickly knock up a prototype, you really can’t miss with the combination. All you need to do is add your dojoType attribute to the html options hash and bingo, dijits abound. Couple this with rails’ ability to quickly turn objects into JSON and in no time you can have an application chock full of dataStore-backed dijit components. I feel like it saves me many hours.

  5. dante Says:

    @cs44 - I did a quick timer around the loading + parsing | instantiating for the two above links … I didn’t update the links yet, but contrary to even my own belief it seems to only be a marginal difference.

    @unscriptable - I long for a day for transparent json-based templates on both server and client side — dojox.dtl goes a long way, wished I had time to play with it. Then it would be a no-brainer.

  6. alex Says:

    unscriptable:

    You can still use declarative in that case, just call dojo.parser.parse(someNodeOfId) on the node you want to have the content parsed on. That’s pretty much all that happens when you set parseOnLoad: true; anyway. It just does something like:

    dojo.addOnLoad(dojo.hitch(dojo.parser, “parse”, document.body));

    Regards

  7. Les1 Says:

    Programmatic way is also a lot more flexible. It’s hard to put any conditional logic in markup, but in JavaScript it obviously is not a problem.

  8. rlamarch Says:

    The nice part about Dojo is that you have the “choice” to do it either way (or a combination of both). I’ve found declarative (with a few static JSON files) to be a very fast way to create an interactive prototype. Down the road I’ve surprised myself expecting to recode a lot on that in programatic style and stayed with the declarative coding.

  9. rct Says:

    When I was getting started I had a lot of trouble trying to mix declarative and programmatic. (I had some things that needed to be dynamic but I still wanted to degrade gracefully). I couldn’t find good examples of what I was trying to do at the time. I eventually found most of the details I needed but it seemed to me that they were a bit scattered around.

    So are there any good resources you’d recommend for getting a good handle on what you need to know when mixing declarative and programmatic?

    Thanks,
    -Rob T.

  10. rlamarch Says:

    @rct - I think the key point would be to set the jsId attribute in your declarative code. Then you can easily reference that widget in your javascript code.

  11. rickoshay Says:

    I would not characterize declarative and programmatic “entirely opposite”; it’s sort of like saying #FFF is the opposite of white. On the other hand, the problem with declaring them equal is that it’s not true. Try taking a programmatic grid that uses onBeforeGrid and declare it using markup. No such property. You might say, that’s easily fixed with documentation, but of course that’s the WORST problem of all with DOJO.

Leave a Reply

You must be logged in to post a comment.