Расширение каждого события Ajax.Request onSuccess (Javascript Prototype Framework)

У меня есть приложение, которое во многих местах использует Ajax.Request и его обработчик событий onSuccess.

Мне нужно вызвать функцию (которая проверит ответ) до того, как все эти onSuccess события сработают. Я пытался использовать Ajax.Responders.register с событием onComplete, но оно срабатывает после события onSuccess Ajax.Request. Какие-либо предложения?


person matte    schedule 13.11.2008    source источник
comment
какой язык вы используете?   -  person Ady    schedule 13.11.2008
comment
Привет, Эди, я использую каркас прототипа javascript.   -  person matte    schedule 13.11.2008


Ответы (6)


Это может быть немного поздно, но для всех, кто интересуется той же проблемой, я предложу это решение:

Для этого можно использовать собственную реализацию аспектно-ориентированного программирования Prototypes. Конечно, вам придется изменить все ваши параметры onSuccess, но это можно сделать с помощью простого поиска и замены вместо обновления всех ваших функций обратного вызова. Вот пример создания Ajax.Request:

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

Скажем, у вас есть похожие фрагменты кода, разбросанные по всему вашему коду, и вы хотите, чтобы им всем предшествовала определенная функция, которая проверяет ответ до того, как фактическая функция будет запущена (или даже вообще не будет запущена). Используя Funtion.wrap, поставляемый в Prototype, мы можем сделать это, расширив приведенный выше код:

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

Где «validateResponse» — это функция, подобная этой:

// 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 */);
    }
}

Таким образом, вы расширили свои onSuccess-функции в одном центральном месте, просто быстро найдя onSuccess и вставив в «wrap (validateResponse)». Это также дает вам возможность иметь несколько функций-оболочек в зависимости от потребностей конкретного Ajax-запроса.

person Aleksander Krzywinski    schedule 11.05.2009

похоже на ответ Александра Крживинского, но я считаю, что это избавит вас от необходимости повсюду использовать «обертку», объединив ее с ответчиком onCreate.

Ajax.Responders.register({

  onCreate: function(request) {

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

  }

});
person seth    schedule 05.02.2010

Существует несколько событий на выбор. Вот цепочка событий для Ajax.Request:

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

onLoading, onLoaded, onInteractive звучат интересно, но согласно спецификации они не гарантируют случаться. Это оставляет вам возможность подключиться к onCreate, который вызывается сразу после создания объекта запроса, но до фактического выполнения запроса.

person Tomalak    schedule 13.11.2008
comment
Привет Томалак, как вы сказали, onCreate вызывается до того, как будет сделан запрос. Но мне нужно обработать ответ, поэтому для меня это не вариант. - person matte; 13.11.2008
comment
Тогда вы хотите onSuccess. Нет никакого способа обойти это. Все, что вы можете сделать, это включить функцию очистки/проверки в начале каждого вызова onSuccess. (Или вы вставляете его в библиотеку Prototype JavaScript, но на этом пути вас ждет безумие.) - person Tomalak; 13.11.2008

Вы можете запустить свой метод перед другим кодом в onSuccess и вернуть false, если что-то не так.

person Mikael Söderström    schedule 13.11.2008
comment
Да, вы правы, но у меня уже везде зарегистрировано много событий onSuccess. То, что я пытаюсь сделать, это просто расширить базу событий onSuccess. - person matte; 13.11.2008
comment
Я понимаю вашу проблему. Но что, если вы создадите новую функцию, использующую Ajax.Request, но сначала добавите свою проверку? Это не сексуальное решение, но оно может сработать. - person Mikael Söderström; 13.11.2008
comment
Это тоже правильно, но если я сделаю так, мне нужно заменить каждый вызов Ajax.Request этой новой функцией. Вам может показаться ленивым, но обращений к Ajax.Request очень много :) - person matte; 13.11.2008

Не знаю, является ли это самым чистым решением, но для меня это помогло.


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;
person Gabi Purcaru    schedule 26.06.2010

«Общее решение» - независимо от JS-фреймворка (типа)

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

Это «расширит» вашу JS-функцию, заставив ее делать точно то, что она делала раньше, за исключением того, что каждый раз перед ее выполнением будет отображаться окно предупреждения...

person Thomas Hansen    schedule 20.11.2008