AJAX In Action [102]
Let’s suppose that we have a script updateDomainModel.jsp running on our server that captures the following information:
■
The unique ID of the planet being updated
■
The name of the property being updated
■
The value being assigned to the property
We can write an event handler to fire all changes to the server like so: function updateServer(propviewer){
var planetObj=propviewer.viewer.object;
var planetId=planetObj.id;
var propName=propviewer.name;
var val=propviewer.value;
net.ContentLoader(
'updateDomainModel.jsp',
someResponseHandler,
null,
'POST',
'planetId='+encodeURI(planetId)
+'&propertyName='+encodeURI(propName)
+'&value='+encodeURI(val)
);
}
Licensed to jonathan zheng 198 CHAPTER 5 The role of the server And we can attach it to our ObjectViewer: myObjectViewer.addChangeListener(updateServer); This is easy to code but can result in a lot of very small bits of traffic to the server, which is inefficient and potentially confusing. If we want to control our traffic, we can capture these updates and queue them locally and then send them to the server in batches at our leisure. A simple update queue implemented in JavaScript is shown in listing 5.13. Listing 5.13 CommandQueue object net.CommandQueue=function(id,url,freq){ b Create a queue object this.id=id; net.cmdQueues[id]=this; this.url=url; this.queued=new Array(); this.sent=new Array(); if (freq){ this.repeat(freq); } } net.CommandQueue.prototype.addCommand=function(command){ if (this.isCommand(command)){ this.queue.append(command,true); } } net.CommandQueue.prototype.fireRequest=function(){ c Send request to server if (this.queued.length==0){ return; } var data="data="; for(var i=0;i if (this.isCommand(cmd)){ data+=cmd.toRequestString(); this.sent[cmd.id]=cmd; } } this.queued=new Array(); this.loader=new net.ContentLoader( this.url, net.CommandQueue.onload,net.CommandQueue.onerror, "POST",data ); } Licensed to jonathan zheng Writing to the server 199 net.CommandQueue.prototype.isCommand=function(obj){ d Test object type return ( obj.implementsProp("id") && obj.implementsFunc("toRequestString") && obj.implementsFunc("parseResponse") ); } net.CommandQueue.onload=function(loader){ e Parse server response var xmlDoc=net.req.responseXML; var elDocRoot=xmlDoc.getElementsByTagName("commands")[0]; if (elDocRoot){ for(i=0;i if (elChild.nodeName=="command"){ var attrs=elChild.attributes; var id=attrs.getNamedItem("id").value; var command=net.commandQueue.sent[id]; if (command){ command.parseResponse(elChild); } } } } } net.CommandQueue.onerror=function(loader){ alert("problem sending the data to the server"); } net.CommandQueue.prototype.repeat=function(freq){ f Poll the server this.unrepeat(); if (freq>0){ this.freq=freq; var cmd="net.cmdQueues["+this.id+"].fireRequest()"; this.repeater=setInterval(cmd,freq*1000); } } net.CommandQueue.prototype.unrepeat=function(){ g Switch polling off if (this.repeater){ clearInterval(this.repeater); } this.repeater=null; } The CommandQueue object (so called because it queues Command objects