AJAX In Action [196]
'field1_updater'. The XML we expect to come back to this component should have a response element that looks like this:
...same xml content as before.
Internally, we will be sending requests via the following:
ajaxEngine.sendRequest( ' field1_request',
'param1=val1', 'param2=val2', ... );
With that in mind, there are two things we have to do from the client to make our component Ajax enabled: send the request and handle the response. Let’s look at each in turn.
Text suggest—sending the Ajax request
Obviously there’s a little bit of work involved in getting to the point where we can send a request. The text input will have to generate an onchange event that we will listen to and conditionally send a request for the suggestions. We’ve not put any of that code in place yet, but that’s okay. We can still think in terms of our method responsibilities and the contracts we’d like to enforce independently of that being done. So, let’s assume that some piece of code yet to be written will decide that it needs to send a request to get some suggestions. Let’s call it sendRequestForSuggestions() and implement it as follows: sendRequestForSuggestions: function() {
if ( this.handlingRequest ) {
this.pendingRequest = true;
return;
}
this.handlingRequest = true;
this.callRicoAjaxEngine();
},
Licensed to jonathan zheng Refactoring 403 All this code does is to conditionally call this.callRicoAjaxEngine() if a request is not still being processed. This simple mechanism turns an internal boolean property, this.handlingRequest, to true as soon as an Ajax request is made and back to false (shown later) once the request has been handled. This is a very simple mechanism to use to throttle the sending of events based on the speed of the server. The boolean property this.pendingRequest is set to true if the method is called while a request is currently being processed. This state will let the handler know that it may have to send another request once the one being processed is finished. Now let’s peek under the hood and look at the callRicoAjaxEngine() method shown in listing 10.23. Listing 10.23 Using the Rico ajaxEngine callRicoAjaxEngine: function() { var callParms = []; callParms.push( this.id + '_request'); Build the callParms.push( 'id=' + this.id); parameter callParms.push( 'count=' + this.options.count); array callParms.push( 'query=' + this.lastRequestString); callParms.push( 'match_anywhere=' + this.options.matchAnywhere); callParms.push( 'ignore_case=' + this.options.ignoreCase); var additionalParms = this.options.requestParameters || []; for( var i=0 ; i < additionalParms.length ; i++ ) callParms.push(additionalParms[i]); ajaxEngine.sendRequest.apply( ajaxEngine, callParms ); Send the Ajax request }, To understand what this method does, we first need to talk about a JavaScript mechanism we are making use of on the very last line of the method: ajaxEngine.sendRequest.apply( ajaxEngine, callParms ); This uses a method called apply(), which is available to all function objects (see appendix B for more details). Let’s illustrate the usage with a simpler example: Greeter.prototype.greetPeople = function(str1, str2) { alert('hello ' + str1 + 'and ' + str2) }; Suppose we have an instance of Greeter called friendlyPerson, and we want to call the greetPeople() method on that object. But we don’t have the parameters Licensed to jonathan zheng 404 CHAPTER 10 Type-ahead suggest in a form that is easy to pass. We actually have an array of people. This is where the apply method