I like Spry. Why? Simple - they got their data model right.
Not that I’ve done a lot of AJAX work, but from what I’ve seen of other frameworks, it seems that the general focus has been on creating cool UI components. While this is not at all a bad thing, the result is that AJAX data models are not nearly as mature as they could be.
The programming models for most of these frameworks are typically transactional - user performs action on UI, javascipt makes asynchronous call to web server, and registers a callback function to handle the results.
Spry does things quite differently. You start by defining Spry datasets to asynchronously retrieve the data you need to populate on your page, like so:
var dsCategories
= new Spry.Data.XMLDataSet("shoppingcart.cfc?method=getCategories", "categories/category");
var dsItems
= new Spry.Data.XMLDataSet("shoppingcart.cfc?method=getItems&categoryid={dsCategories::categoryid}", "items/item");
var dsDetails
= new Spry.Data.XMLDataSet("shoppingcart.cfc?method=getItemDetails&itemid={dsItems::itemid}", "details/item");
The example above is from a simple shopping cart application I wrote to get a feel for Spry. Note the CFC calls - for those who don’t know, you can invoke CFC methods that have the ‘access=remote’ attribute specified via HTTP calls. Unfortunately, the WDDX XML format that ColdFusion outputs by default for these kinds of calls is not flat enough for Spry to process, so you’ll have to create your own XML dialect and return that from your CFCs - actually, it might even just be easier to create a CFM that outputs the XML.
The Spry datasets load XML returned from the specified URLs, parse it down to the level of the provided XPath expression, and then extract data from that level of the document into a tabular format. Sounds a bit complex? The Spry team has you covered - go take a look at the Spry Dataset and Dynamic Region Overview for a good introduction.
The really interesting part of the dataset definitions, though, is that you can create what virtually amounts to foreign keys between the datasets. The first dataset, dsCategories, loads a set of categories for items that are available in the store. The second dataset, dsItems, loads the set of items for the currently selected category, using the expression {dsCategories::categoryid}. The third dataset, dsDetails loads the details of the currently selected item, using the expression {dsItems::itemid}. You can change the selected entry in a dataset (category or item in this case), and Spry will figure out what datasets depend on the change and reload them automatically - cool, huh?
So I hear you thinking to yourself, datasets, blah, blah, I need to get some data on my UI! Spry introduces the concept of dynamic regions to help you do just that. For example:
<div id="ItemList" spry:detailregion="dsCategories dsItems" class="SpryHiddenRegion" >
<div spry:state="ready" spry:repeat="dsItems">
<div class="ItemColumn" onclick="dsItems.setCurrentRow('{dsItems::ds_RowID}');">
{dsItems::name}
</div>
</div>
</div>
This fragment of code shows how Spry will allow you to loop over the dsItems dataset to display the list of items for the selected category. Note that the outermost div has a spry:detailregion attribute, making it a Spry dynamic region, which points to the datasets, dsCategories and dsItems, that this dynamic region depends on. What does this mean? When a new category is selected in the dsCategories dataset by calling dsCategories.setCurrentRow(’{dsCategories::ds_RowID}’) on click of a category in the category list, the ItemList region is reloaded, since it declares a dependency on the dsCategories dataset. Moreover, the dsItems dataset is also reloaded, since it has a dependency on dsCategories as well, so the list of items that gets displayed is for the selected category.
This is what makes me like Spry so much - you can define dependencies between datasets and display regions, and then not worry about AJAX at all. The programming model is no longer transactional - once the datasets and regions are defined, code deals only with ensuring that the dataset state is maintained properly, typically by grabbing events such as onClick to set the current item in a dataset. There’s none of the conventional worry about setting up a response handler for each event, writing code in that handler to parse the response from the server, and then populating the response elements into the HTML DOM tree.
There is, however, one place where this model breaks down for Spry. If you need to send data to the server, rather than retrieve data from the server, you’re going to have to go the usual route and write callbacks. For example, in order to add an item to the shopping cart, I had to write the following bit of Javascipt:
Spry.Utils.loadURL("post",
"shoppingcart.cfc?method=addItemToCart&name=" + name + "&price=" + price + "&itemid=" + id + "&quantity=" + quantity,
true, null);
Not so cool - I would have much preferred it if Spry allowed me to add a row to the shopping cart dataset and register a listener there which would take care of exactly this kind of interaction. Client-side AJAX datasets with full CRUD capabilities, yum! ![]()
From the Spry forums, I see that it is the stated intention of the Spry team to have Spry play well with just about any other AJAX framework - more wholesome goodness, use your Spry datasets and dynamic regions to wrap UI widgets from OpenRico, MochiKit, Dojo, or whatever suits your fancy. The current version does not, alas, work over Prototype-based frameworks, such as OpenRico, but that should be resolved with the next release. For those who want Prototype support now, check out Big Doug’s Spry Patches.
Spry is still an early beta - I, for one, am looking forward to seeing what this framework looks like when it gets to final release.

Teddy R Payne | 03-Aug-06 at 1:34 pm | Permalink
Spry in a very simple approach is the ColdFusion for AJAX. Spry is creating approachable AJAX code that will help bridge the gap between structure language people and the design communities.
Spry is an exciting opportunity to really get ColdFusion centric people into yet another avenue to create immersive web experiences.
Sam Curren | 03-Aug-06 at 3:06 pm | Permalink
I wish we had a way to specify returntype encoding for remote CFC calls. WDDX isn’t bad, but a JSON option would be nice, or better yet, the ability to specify a function that does the output formatting, so that we could define our own XML formatting function, and then use it to format the output of many remote methods.
ashwin | 04-Aug-06 at 9:45 am | Permalink
Well said, Sam! As a workaround, you could use a CFM to generate your output, which would be a good deal easier and cleaner than constructing an output string inside a CFC - all you need to do is stick CFML inside and around your JSON/XML. If you really need output from a CFC, perhaps ColdSpring is your friend; add an output formatter advice to your CFC functions that will turn your CFML types in XML/JSON.
Raymond Camden | 13-Aug-06 at 7:30 pm | Permalink
Hey Sam, don’t forget that in cf7, if you use returnType=”xml”, CF will NOT wddx-ify your result.
Najier | 14-Nov-06 at 4:30 pm | Permalink
Do u have an example of how to use both Dojo and Spry together?
ashwin | 15-Nov-06 at 5:27 am | Permalink
I haven’t tried that combination myself, Najier. You might want to check the Spry forums to see whether other people have gone that route.
michael | 25-Nov-07 at 11:16 pm | Permalink
so now there is a dojo 1.0 and spry 1.6 do you still think it’s a better method ?
I am looking at both at the current time, Dojo seems to be a little more comprehensive but far more work to get the job done. Spry seems to be a little more straight forward. but I have only been looking at them for a week now.
Ashwin | 25-Nov-07 at 11:38 pm | Permalink
Depends on what you want to achieve, Michael - I think Spry and the new ColdFusion 8 AJAX tags offer solutions for almost all needs a normal AJAX application will need. However, if you need to customize application behaviour in highly specialized ways (e.g., control particular animations, transparencies, etc.) then something like Dojo, Prototype, or MooTools might be a better choice.