AJAX In Action [98]
5.4.5 Thinking like an application: data-centric interactions
With the script-centric approach just described, we have started to behave more like a traditional thick client, with data requests to the server taking place in the background, decoupled from the user interface. The script content remained highly specific to the browser-based client, though.
Overview
In some situations, we may want to share the data feeds to our Ajax client with other front ends, such as Java or .NET smart clients or cell phone/PDA client software. In such cases, we would probably prefer a more neutral data format than a set of JavaScript instructions.
In a data-centric solution, the server serves up streams of pure data, which our own client code, rather than the JavaScript engine, parses. Figure 5.9 illustrates the features of a data-centric solution.
Most of the examples in this book follow a data-centric approach. The most obvious format for data is XML, but other formats are possible, too, as we’ll see next.
Using XML data
XML is a near-ubiquitous data format in modern computing. The web browser environment in which our Ajax application sits, and the XMLHttpRequest object Client
Server
Request object
1. Request
Title
Item
Item
2. Response
Item
3. Parse
4. Update visible elements
Figure 5.9 In a data-centric system, the server returns streams of raw data (XML in this case), which are parsed on the client tier and used to update the client tier model and/or user interface.
Licensed to jonathan zheng The details: exchanging data 189 in particular, provides good native support for processing XML. If the XMLHttpRequest receives a response with an XML Content type such as application/ xml or text/xml, it can present the response as a Document Object Model, as we have already seen. Listing 5.7 shows how our planetary data application adapts to using XML data feeds. Listing 5.7 DataXMLPopup.js var offset=8; function showPopup(name,description){ var win=new DataPopup(name,description,offset,offset,320,320); offset+=32; } function DataPopup(name,description,x,y,w,h){ var bod=document.createElement("div"); document.body.appendChild(bod); this.contentDiv=document.createElement("div"); this.contentDiv.className="winContents"; this.contentDiv.innerHTML=description; bod.appendChild(this.contentDiv); this.win=new windows.Window(bod,name,x,y,w,h); } function showInfo(event){ var planet=this.id; var scriptUrl=planet+".xml"; new net.ContentLoader(scriptUrl,parseXML); } function parseXML(){ var name=""; var descrip=""; var xmlDoc=this.req.responseXML; var elDocRoot=xmlDoc.getElementsByTagName("planet")[0]; if (elDocRoot){ attrs=elDocRoot.attributes; name=attrs.getNamedItem("name").value; var ptype=attrs.getNamedItem("type").value; if (ptype){ descrip+=" } descrip+=" for(var i=0;i Licensed to jonathan zheng 190 CHAPTER 5 The role of the server if (elChild.nodeName=="info"){ descrip+=" } } descrip+=" }else{ alert("no document"); } top.showPopup(name,descrip); } The showInfo() function simply opens up an XMLHttpRequest object, wrapped up in a ContentLoader object, providing the parseXML() function as a callback. The callback here is slightly more involved than the evalScript() method that we encountered in section 5.6.3, as we have to navigate the response DOM, pull out the data, and then manually invoke the showPopup() method. Listing 5.8 shows an example XML response generated by the server, which our XML data-centric app might consume. Listing 5.8 earth.xml"+ptype+"
";";
";