Declarative Ajax and Flex Interop 
July 3rd, 2007
This is some code that I wrote about a year ago at the Flex Component Developers Summit (and more recently presented at XTech) to show how declarative Ajax and Flex can work together to create dynamic, rich and compelling Internet applications.
The idea is simple. Take a single declaration - in this case XHTML - of some user-interface component and then use it to build a UI using either Ajax or Flex. All this from just one declaration.
What happens is that we take a single declarative data grid and converts it using XSLT on the client (so it only works Firefox, IE and soon Safari) into a declarative Nitobi Ajax Grid and to a Flex declarative MXML DataGrid. I use the FABridge to get the string of MXML generated from the XSL transformation into a stub Flex application where a Flex DataGrid is instantiated (deserialized) from the MXML declaration. It can an be seen live here (note: create the Flex grid first then the Ajax one - something funny that I can’t be bothered to fix
) and the code can be downloaded from here.
So by using a declarative approach and a little XSLT on the client we were able to quickly choose between using a Flex DataGrid or a Nitobi Ajax Grid to display our tabular data in!
Really the most interesting part is the MXML deserialization stuff. The only contents of the Flex application are two functions for performing the deserialization. I have listed the main part of the code that takes an XML document of an MXML DataGrid declaration and actually instantiates a DataGrid according to that declaration. It’s pretty quick and dirty but at least gets the right thing out! Essentially it just looks at each XML element and creates an Object out of it and sets all the properties on it from the XML element attributes and then recurses through the child elements doing the same. There are some special attributes though like datasources that need a little more care.
public function initGrid(html) {
// setup a tagname to datatype hash - maybe this already exists somewhere
controls['DataGrid'] = 'mx.controls.DataGrid';
controls['ArrayCollection'] = 'mx.collections.ArrayCollection';
controls['Object'] = 'Object';
controls['columns'] = 'Array';
controls['DataGridColumn'] = 'mx.controls.dataGridClasses.DataGridColumn';
// load the HTML into XML DOM
var mxml:XML = new XML('<root>'+html+'</root>');
parseXml(AjaxBox, mxml);
}
public function parseXml(parent, mxml) {
var item:String;
// get all the elements in our XML doc - this should of course walk the xml tree recursively
var itemList:XMLList = mxml.elements('*');
for (item in itemList) {
// get the tag name of the XML node
var tagName:String = itemList[item].localName();
// get the class by using getDefinitionByName() method
var ClassReference:Class = Class(getDefinitionByName(controls[tagName]));
// create an instance of the class
var myObject:Object = new ClassReference();
// get all the attributes and set the properties
var attrList:XMLList = XML(itemList[item]).attributes();
for (var attr:String in attrList) {
myObject[attrList[attr].localName()] = attrList[attr].toString();
}
// now parse the children of this node
parseXml(myObject, itemList[item]);
if (parent.hasOwnProperty(tagName)) {
parent[tagName] = myObject;
} else if (parent.hasOwnProperty("length")) {
if (parent.hasOwnProperty("source")) {
parent.source.push(myObject);
} else {
parent.push(myObject);
}
} else if (parent.hasOwnProperty("dataProvider") && tagName == "ArrayCollection") {
// This means we need to create a datasource for the Grid
parent.dataProvider = myObject;
} else {
parent.addChild(DisplayObject(myObject));
}
}
}

