XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

An AJAX Caching Strategy
by Bruce Perry | Pages: 1, 2, 3

Import the JavaScript

The web application uses script tags in the HTML to import the necessary JavaScript, including the Prototype library. The first xml.com article I wrote on this application shows how to download and set up Prototype.

<head>...
<script src="http://www.eeviewpoint.com/js/prototype.js" type="text/javascript">
</script>
<script src="http://www.eeviewpoint.com/js/eevpapp.js" 
type="text/javascript">
</script>
..</head>

Set Up the Refresh Buttons

First I'll show the code from eevapp.js that I used to get the energy prices. Then I'll show the object that acts as a kind of request filter.

//When the browser has finished loading the web page,
//fetch and display the energy prices
window.onload=function(){
    //generatePrice method takes two parameters:
    //the energy type (e.g., oil) and the id of the
    //span element where the price will be displayed
    generatePrice("oil","oilprice");
    generatePrice("fuel","fuelprice");
    generatePrice("propane",
            "propaneprice");
    
    //set up the Refresh buttons for    
    //getting updated oil, gasoline, and 
    //propane prices.
    //Use their onclick event handlers.    
    $("refresh_oil").onclick=function(){ 
        generatePrice("oil","oilprice"); }
    $("refresh_fuel").onclick=function(){ 
        generatePrice("fuel","fuelprice"); }
    $("refresh_propane").onclick=function(){ 
        generatePrice("propane",
            "propaneprice"); }
    
};

The code comments explain what's going on here. The one odd syntactical segment that needs explanation is the $("refresh_oil").onclick type of expression.

Prototype has a $() function that returns a Document Object Model (DOM) Element object. This Element is associated with the HTML id attribute that the code passes into the $() function as a string parameter. This syntax is the equivalent of writing document.getElementById("refresh_oil"), but it's shorter and therefore handier for the developer. What does "refresh_oil" refer to? This is the id of the Refresh button on the web page. See the left column in the browser screen depicted by Figure 1-1 for a view of the Refresh button.

<input type="submit" id="refresh_oil" .../>

The code sets the onclick event handler of this button to a function that will optionally seek to grab a new energy price. Optionally, meaning that our filter will decide whether or not to launch an HTTP request.

Check the CacheDecider Object First

The generatePrice() function first checks with a cache-related object called CacheDecider to determine whether a new HTTP fetch of an energy price can be initiated. Each energy category--oil, gasoline, and propane--has its own CacheDecider object. The code stores these objects in a hash named cacheHash. Therefore, the expression cacheHash["oil"] will return the CacheDecider object for oil prices.

If the CacheDecider or filter allows the code to make a new HTTP request (CacheDecider.keepData() returns false), then the code calls getEnergyPrice() to refresh, say, the crude oil price. The code comments explain exactly what's going on.

/*Check the CacheDecider object to determine
if a new energy price should be fetched*/
function generatePrice(energyType, elementID){
    //set the local variable cacher to the CacheDecider
    //object associated with oil, gas, or propane
    var cacher = cacheHash[energyType];
    //If this object is null, then a CacheDecider object
    //has not yet been instantiated for the
    //specified energy type.
    if(! cacher) {
        //CacheDecider has a parameter that
        //specifies the number of seconds to keep
        //the data, here 24 hours
        cacher = new  CacheDecider(60*60*24); 
        //store the new object in the hash with
        //the energy type, say "oil", as the key
        cacheHash[energyType]=cacher;
        //Fetch and display the new energy price
        getEnergyPrice(energyType, elementID);
        return;
    }
    //The CacheDecider has already been instantiated, so
    //check whether the currently displayed energy price
    //is stale and should be updated.
    if(! cacher.keepData()) { 
        getEnergyPrice(energyType, elementID);}
}
/*
Use Prototype's Ajax.Request object to fetch an energy price.
Parameters: 
energyType is oil, fuel, or propane.
elementID is the id of a span element on the web page;
the span will be updated with the new data.
*/
function getEnergyPrice(energyType, elementID){

  new Ajax.Request(go_url, {method: "get",
      parameters: "priceTyp="+energyType,
      onLoading:function(){ $(elementID).innerHTML=
                              "waiting...";},
      onComplete:function(request){
          if(request.status != 200) {
            $(elementID).innerHTML="Unavailable."
          }   else {
            $(elementID).innerHTML=
            request.responseText;}
      }});

}

Pages: 1, 2, 3

Next Pagearrow