AJAX In Action [170]
c Here our method uses the getTransport method we defined in listing 9.6 to create an instance of an XMLHttpRequest object. Then the request is opened and its Content-Type header is initialized as in previous examples. The object reference is held in a local variable named request.
d This step takes care of the response-handling task. I’ll bet you’re wondering why the variable oThis was created. You’ll note that the following line—an anonymous function that responds to the onreadystatechange of our request object—references oThis. The name for what’s going on here is a closure. By virtue of the inner Licensed to jonathan zheng 350 CHAPTER 9 Dynamic double combo function referencing the local variable, an implicit execution context or scope is created to allow the reference to be maintained after the enclosing function exits. (See appendix B for more on closures.) This lets us implement handling of the Ajax response by calling a first-class method on our ajaxHelper object. e Finally, we send the Ajax request. Note that the array we created in step 1 is passed to a method named queryString that converts it to a single string. That string becomes the body of the Ajax request. The queryString method isn’t really part of the public contract we discussed earlier, but it’s a helper method that keeps the code clean and readable. Let’s take a look at it in listing 9.8. Listing 9.8 The queryString method queryString: function(args) { var requestParams = []; for ( var i = 0 ; i < this.requestParams.length ; i++ ) { Constant requestParams.push(this.requestParams[i]); parameters } for ( var j = 0 ; j < args.length ; j++ ) { Runtime requestParams.push(args[j]); parameters } var queryString = ""; if ( requestParams && requestParams.length > 0 ) { for ( var i = 0 ; i < requestParams.length ; i++ ) { queryString += requestParams[i] + '&'; } queryString = queryString.substring(0, queryString.length-1); } return queryString; }, This method takes the request parameters that our net.ContentLoader was constructed with, along with the additional runtime parameters that were passed into the sendRequest method, and places them into a single array. It then iterates over the array and converts it into a querystring. An example of what this achieves is shown here: var helper = new net.ContentLoader( someObj, someUrl, "POST", ["a=one", "b=two"] ); var str = ajaxHelper.queryString( ["c=three", "d=four"] ); str => "a=one&b=two&c=three&d=four" Licensed to jonathan zheng Refactoring 351 The last thing we need to do to have a fully functional helper object is to collaborate with a component to handle the response that comes back from Ajax. If you’ve been paying attention, you probably already know what this method will be named. Our sendRequest method already specified how it will handle the response from the onreadystatechange property of the request: request.onreadystatechange = function(){ oThis.handleAjaxResponse(request) } That’s right, kids; all we need to do is implement a method named handleAjaxResponse. Listing 9.9 contains the implementation. Listing 9.9