AJAX In Action [60]
function Vehicle(numWheels,maxSpeed){
this.numWheels=numWheels;
this.maxSpeed=maxSpeed;
}
for which we want to define a specific instance that represents a passenger train. In our child class we also want to represent the number of carriages and provide a mechanism for adding and removing them. In ordinary JavaScript, we could write
var passTrain=new Vehicle(24,100);
passTrain.carriageCount=12;
passTrain.addCarriage=function(){
this.carriageCount++;
}
passTrain.removeCarriage=function(){
this.carriageCount--;
}
This provides the required functionality for our passTrain object. Looking at the code from a design perspective, though, it does little to wrap up the extended functionality into a coherent unit. Prototype can help us here, by allowing us to define the extended behavior as an object and then extend the base object with it. First, we define the extended functionality as an object:
function CarriagePuller(carriageCount){
this.carriageCount=carriageCount;
this.addCarriage=function(){
this.carriageCount++;
}
this.removeCarriage=function(){
this.carriageCount--;
}
}
Licensed to jonathan zheng Third-party libraries and frameworks 107 Then we merge the two to provide a single object containing all of the required behavior: var parent=new Vehicle(24,100); var extension=new CarriagePuller(12); var passTrain=Object.extend(parent,extension); Note that we define the parent and extension objects separately at first and then mix them together. The parent-child relationship exists between these instances, not between the Vehicle and CarriagePuller classes. While it isn’t exactly classic object orientation, it allows us to keep all the code related to a specific function, in this case pulling carriages, in one place, from which it can easily be reused. While doing so in a small example like this may seem unnecessary, in larger projects, encapsulating functionality in such a way is extremely helpful. Prototype also provides Ajax support in the form of an Ajax object that can resolve a cross-browser XMLHttpRequest object. Ajax is extended by the Ajax.Request type, which can make requests to the server using XMLHttpRequest, like so: var req=new Ajax.Request('myData.xml'); The constructor uses a style that we’ll also see in many of the Prototype-based libraries. It takes an associative array as an optional argument, allowing a wide range of options to be configured as needed. Sensible default values are provided for each option, so we need only pass in those objects that we want to override. In the case of the Ajax.Request constructor, the options array allows post data, request parameters, HTTP methods, and callback handlers to be defined. A more customized invocation of Ajax.Request might look like this: var req=new Ajax.Request( 'myData.xml', { method: 'get', parameters: { name:'dave',likes:'chocolate,rhubarb' }, onLoaded: function(){ alert('loaded!'); }, onComplete: function(){ alert('done!\n\n'+req.transport.responseText); } } ); The options array here has passed in four parameters. The HTTP method is set to get, because Prototype will default to the HTTP post method. The parameters array will be passed down on the querystring, because we are using HTTP get. If we used POST, it would be passed in the request body. onLoaded and onComplete are Licensed to jonathan zheng 108 CHAPTER 3 Introducing order to Ajax callback event handlers that will be fired when the readyState of the underlying XMLHttpRequest object changes. The variable req.transport in the onComplete function is a reference to the underlying XMLHttpRequest object. On top of Ajax.Request, Prototype further defines an Ajax.Updater type