Online Book Reader

Home Category

AJAX In Action [111]

By Root 4014 0
status='ok'/>

Alongside the tags, which are identified by the ID of the Command object in the sent queue, there is an tag, which in this case denotes that the distance from the sun of Venus has been set to a value of 0.76 by another user called Jim. We have also added an attribute to the top-level tag, the purpose of which we explain shortly.

Previously, our command queue sent requests to the server only if there were commands queued up. We would need to modify it now to poll the server even if the queue were empty, in order to receive updates. Implementing this touches upon the code in several places. Listing 6.1 shows the revised CommandQueue object, with the changes in bold.

Listing 6.1 CommandQueue object

net.cmdQueues=new Array(); b

Global lookup

net.CommandQueue=function(id,url, onUpdate,freq){ c

Extra parameters

this.id=id;

net.cmdQueues[id]=this;

this.url=url;

this.queued=new Array();

this.sent=new Array();

Licensed to jonathan zheng

Keeping the user informed

219

this.onUpdate=onUpdate;

if (freq){ d Polling initializer

this.repeat(freq);

}

this.lastUpdateTime=0;

}

net.CommandQueue.prototype.fireRequest=function(){

if (!this.onUpdate && this.queued.length==0){

return;

}

var data="lastUpdate="+this.lastUpdateTime+"&data="; Timestamp requests

for(var i=0;ivar cmd=this.queued[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

);

}

net.CommandQueue.onload=function(loader){

var xmlDoc=net.req.responseXML;

var elDocRoot=xmlDoc.getElementsByTagName("responses")[0]; var lastUpdate=elDocRoot.attributes.getNamedItem("updateTime"); if (parseInt(lastUpdate)>this.lastUpdateTime){

this.lastUpdateTime=lastUpdate; e

Updated timestamp

}

if (elDocRoot){

for(i=0;ielChild=elDocRoot.childNodes[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);

}

}else if (elChild.nodeName=="update"){

if (this.implementsFunc("onUpdate")){

this.onUpdate.call(this,elChild); f

Updated handler

}

}

Licensed to jonathan zheng

220

CHAPTER 6

The user experience

}

}

}

net.CommandQueue.prototype.repeat=function(freq){ g

Server poller

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(){ h

Polling switch

if (this.repeater){

clearInterval(this.repeater);

}

this.repeater=null;

}

We’ve added quite a bit of new functionality here. Let’s step through it. First, we’ve introduced a global lookup of command queue objects b. This is a necessary evil given the limitations of the setInterval() method, which we’ll discuss shortly. The constructor takes a unique ID as an argument and registers itself with this lookup under this key.

The CommandQueue constructor now takes two other new arguments c.

onUpdate is a Function object that is used to handle the tags that we introduced into our response XML. freq is a numerical value indicating the number of seconds between polling the server for updates. If it is set, then the constructor initializes a call to the repeat() function g, which uses JavaScript’s builtin setInterval() method to regularly execute a piece of code. setInterval() and its cousin setTimeout()accept only strings as arguments under Internet Explorer, so passing variable references directly into the code to be executed is not possible. We use the global lookup variable and the unique ID of this queue to develop a workaround to this problem in the repeat() method.

Return Main Page Previous Page Next Page

®Online Book Reader