Monday, March 12, 2012

In the 1.6 release of Dojo, a new Store API was released with the intentions of improving on the design of the
Data API. While I agree with most of the new Store API design, there is one feature of the Data API that I make
significant use of and it was not carried forward into the Store API. The missing feature is the data structure
that is used to initialize the store. In this post I will discuss why I find it important and create a store that
uses the legacy structure and also implements the new Store API.

I use a data store as a page view model providing the needed data to the widgets on the page. The data has many
references and I want to be able to query the store for any object within it. The legacy Data API uses a flat
list of items. Any references to other items are identified using a "_reference" attribute. When the store initializes,
it will replace the "_reference" object with the actual object. This allows for a normalized model
with all objects queryable in the store.

The Data

For this example, the view model contains multiple orders. I want to be able to create a combobox
with all of the customers and a combobox with all possible order statuses. The orders that are shown
should match the customer and order status selected in the comboboxes.

The ViewModelStore extends the MemoryStore and the core component is the implementation of setData. Here, each item in the array is registered. After an item is registered and if previous objects contain a reference to the object, a setter function will be called and the reference to the newly registered object will be set. Using the data above as an example, after registering the address object, a previously registered setter function will be called to set the address property of the customer to this address object.

Registering an item determines if it is an array or not. If so, it will call the inspectValue function for each item of the array, otherwise it is called for the item itself. The inspectValue function determines if it is a reference to another object in the data. If it isn't, then there is nothing more to do. If it is a reference and the referenced item has already been registered, then that item replaces the object identified by the reference. If the item has not been registered, then a function to set the value is registered to be called when the reference is registered.

The code snippet below creates two comboboxes and populates them using the data from the store. The onChange events
are then wired to a function that queries the store using the filters specified in the comboboxes and renders the orders.
If a new status is to be added later, it simply has to be put into the view model and the page will handle it accordingly.

Monday, March 5, 2012

When using the Dojo Toolkit in an application, I setup the application so that one of three different configurations can be used. There is a production, an uncompressed, and a debug configuration. Each of these configurations can be used to load the Dojo Toolkit and any custom javascript.The production configuration uses the output of the Dojo build. The javascript files are minified and combined into a single file. This is the default configuration and used by default. Since this code is minified, it is very hard to debug.

As part of the Dojo build process, a second set of files are created. These files end in .uncompressed.js. The uncompressed configuration uses these files. It is still a single file for javascript and loads fast, but the javascript code is human readable. This makes it easier to step through code using a browser's javascript debugger. While it is easy to debug, it still requires a build cycle to deploy changes.

The third configuration is the debug configuration. This configuration points directly at the source code and does not use the build process. This is noticeably slower when loading pages because the browser is loading many files but this configuration doesn't require a build to see changes made to source.

When an application is deployed, the debug configuration is not made available. The production configuration is the default and having the uncompressed available allows a developer to troubleshoot a problem on an end user's machine. The debug configuration is valuable when developing a significant piece of javascript and you do not want to be continually building to see your changes.

ImplementationI use a query string parameter to specify a different configuration. This requires server side code to interpret the query string value and swap out a configuration. You may find it useful for the server code to place the value in the session. Doing so allows yout to navigate to different pages without continuing to modify the query string.A simplified folder structure is:static dojo-release dojo dojo.js dojo.js.uncompressed.js myDojoCode custom-dojo.js custom-dojo.js.uncompressed.js dojo-source* dojo dojo.js myDojoCode [a bunch of custom javascript files]

* only exists on development machines

The HTML output when using the production configuration would look something like:

dojo.js is the core dojo kernal and custom-dojo.js contains the auxiliary javascript code in a single file. The source of this code exists in multiple files in the source folder. In the debug configuration, we do not include an all encompassing file because we want Dojo to load the individual source files.