admin管理员组

文章数量:1278910

I have an application that uses Ajax.Request and its onSuccess event handler in lots of places.

I need to call a function (that will check the response) before all these onSuccess events fire. I tried using Ajax.Responders.register with onComplete event but it fires after Ajax.Request's onSuccess event. Any suggestions?

I have an application that uses Ajax.Request and its onSuccess event handler in lots of places.

I need to call a function (that will check the response) before all these onSuccess events fire. I tried using Ajax.Responders.register with onComplete event but it fires after Ajax.Request's onSuccess event. Any suggestions?

Share Improve this question edited Dec 28, 2011 at 20:49 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Nov 13, 2008 at 9:16 mattematte 1,2464 gold badges14 silver badges21 bronze badges 2
  • which language are you using? – Ady Commented Nov 13, 2008 at 9:21
  • Hi Ady, i am useing javascript prototype framework – matte Commented Nov 13, 2008 at 9:22
Add a ment  | 

6 Answers 6

Reset to default 4

similar to Aleksander Krzywinski's answer, but I believe this would prevent you from having to sprinkle the use of "wrap" everywhere, by consolidating it to the onCreate Responder.

Ajax.Responders.register({

  onCreate: function(request) {

    request.options['onSuccess'] = request.options['onSuccess'].wrap(validateResponse);

  }

});

There are several events to chose from. Here is the event chain for Ajax.Request:

  1. onCreate
  2. onUninitialized
  3. onLoading
  4. onLoaded
  5. onInteractive
  6. onXYZ, onSuccess or onFailure
  7. onComplete

onLoading, onLoaded, onInteractive sound interesting, but according to the spec they are not guaranteed to happen. That leaves you with the possibility to hook on to onCreate, which is called just after the request object is build, but before the request is actually made.

This might be a little late, but for the benefit of anyone else wondering about the same problem I will propose this solution:

You can use Prototypes own implementation of aspect-oriented programming to do this. Granted you will have to modify all your onSuccess-parameters, but it can be done with a simple search-and-replace, instead of updating all your callback functions. Here is an example Ajax.Request creation:

new Ajax.Request('example.html', {
    parameters: {action: 'update'},
    onSuccess: this.updateSuccessful
});

Say you have similar code snippets spread all over your code, and you want to preceed them all with a certain function that validates the response before the actual function is run(or even prevented from running at all). By using Funtion.wrap supplied in Prototype we can do this by extending the code above:

new Ajax.Request('example.html', {
    parameters: {action: 'update'},
    onSuccess: this.updateSuccessful.wrap(validateResponse)
});

Where 'validateResponse' is a function similar to this:

// If you use the X-JSON-header of the response for JSON, add the third param
function validateResponse(originalFn, transport /*, json */) {
    // Validate the transport

    if (someConditionMet) {
        originalFn(transport /*, json */);
    }
}

Thus you have extended your onSuccess-functions in one central place with just a quick search for onSuccess and pasting in 'wrap(validateResponse)'. This also gives you the option of having several wrapper-functions depending on the needs of the particular Ajax-request.

You can run your method before the other code in onSuccess and return false if something is wrong.

Don't know if this is the cleanest solution, but for me it did the trick.


var tmp = Ajax.Request;
Ajax.Request = function(url, args) {
 // stuff to do before the request is sent
 var c = Object.clone(args);
 c.onSuccess = function(transport){
  // stuff to do when request is successful, before the callback
  args.onSuccess(transport);
 }

 var a = new tmp(url, c);
 return a;
}
Ajax.Request.protoype = new tmp();
Ajax.Request.Events = tmp.Events;
delete tmp;

"General solution" - independent upon JS framework (kind of)

var oldFunc = Ajax.Request.onSuccess;
Ajax.Request.onSuccess = function foo() {
  alert('t');
  oldFunc.apply(this, arguments);
}

This will "extend" your JS function making it do exactly what it used to do except show an alert box every time before it executes...

本文标签: Extending every AjaxRequest onSuccess event (Javascript Prototype Framework)Stack Overflow