В этот момент я заканчиваю переписывание нашей системы JavaScript, мы переходим от Prototype к jQuery.У нас есть загрузка AJAX-запросов, которые запускаются при возникновении определенных событий элемента, в приведенном ниже примере это новое событие в календаре, но оно происходит и в других местах.
Проблема, которую я получаю, заключается в том, когдасобытие запускается иногда два AJAX-запроса.Первый возвращает правильное значение, но (как вы можете видеть) он все еще говорит об обработке, он никогда не возвращает сообщение об успешном выполнении, которое требует мой JavaScript.Второй запрос возвращает правильный результат И завершается правильно.
Проблема, с которой я столкнулся, заключается в том, что наш блокировщик экрана jQuery настроен на предотвращение пользовательского ввода во время тяжелых запросов AJAX, очевидно, потому что запрос AJAX все еще жив, экран никогда не разблокируется.Если я обновлю этот экран, все будет работать так, как нужно.
Может ли кто-нибудь пролить свет на то, почему это происходит.
alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request.png
РЕДАКТИРОВАТЬ
«Запросы, которые запускаются, когда происходят события определенного элемента» - это ключевая фраза, я думаю.Пожалуйста, предоставьте некоторую информацию о том, как вы устанавливаете свои события.Может быть, он срабатывает дважды, потому что у вас установлено несколько обработчиков?- Игорь Зиновьев
Хорошо, дело в том, что когда я нажимаю «Обновить», проблема обычно разрешается сама собой, поэтому не уверен, как это может быть проблемой с обработчиком, вот обработчик событий, который мы обычно используем для измененияокна выбора.
$("#my_select","#context").change(function(){
// uz_ajax is a wrapper function, keeps most of the same functionality as $.ajax()
uz_ajax({
target:"#my_target",
data:{
module:'my_module',
controller:'my_controller',
action:'my_action',
id:$(this).val(),
ajax:''
}
});
});
Проблема, с которой я столкнулся, заключается в том, что я понятия не имею, как воспроизвести проблему, поэтому я не знаю, запускается ли событие несколько раз или запрос AJAX выполняется дважды.
РЕДАКТИРОВАТЬ 2
Если вы перезагружаете связанные элементы, то события изменения могут запускаться рекурсивно ... Нам действительно нужно увидеть больше кода(что вы делаете в случае успеха вызова ajax и т. д.) - redsquare
Спасибо, redsquare, при успешном запросе AJAX я обычно применяю ответ (обычно HTML <option>
s) к цели.Я никогда не инициирую изменение элемента, который запустил AJAX, но иногда я запускаю изменение целевого элемента, чтобы разрешить каскадные запросы AJAX.Если бы это была проблема, конечно, это будет происходить все время?Моя функция-обёртка uz_ajax
находится ниже:
var ajax_count = 0;
var ajax_response = null;
function uz_ajax(options) {
// set default options
var defaults = {
async: true,
type: "GET",
data: {},
url: "/",
cache: false,
force_change: true,
highlight: true,
action: "normal",
dataType: "html",
selected: {
value: null,
disabled: false
}
};
// merge the passed options with the defaults
var options = $.extend(defaults, options);
// start the jQuery ajax method
$.ajax({
async: options.async,
type: options.type,
url: options.url,
data: options.data,
beforeSend: function() {
// we only want to block the screen on the first pass
if(++ajax_count==1) {
$.blockUI({message:'Loading data, please wait'});
}
},
success: function(responseText) {
if(options.target!==undefined) {
// if target isn't an array, make it one
if(!$.isArray(options.target)) {
options.target = new Array(options.target);
}
var targets = options.target;
for ( var i in targets ) {
console_info("uz_ajax() --> Applying contents to "+targets[i]);
switch(options.action) {
case "normal":
if($(targets[i]).is("input")) {
$(targets[i]).val(trim(responseText));
} else {
$(targets[i]).html(trim(responseText));
}
break;
case "selected":
// preserve the current target value (e.g. list of options), but
// set the selected value to the ajax response
console_warn("Changing selected value of "+targets[i]+" to '"+responseText+"'");
// trim the response so we don't get any smarty induced errors such as ' 7'
$(targets[i]).val(trim(responseText));
break;
}
// set selected value
if(options.selected.value!=null) {
$(targets[i]).val(options.selected.value);
}
// highlight the target
// we don't want to highlight the target if it's a hidden input, as this will force a .show(
if($(targets[i]).attr('type')!='hidden' && options.highlight===true) {
$(targets[i]).effect("highlight",{},2000);
}
// force the target to change
if(options.force_change===true) {
$(targets[i]).trigger("change");
}
/* rebind certain elements that do not use conventional events */
/* We probably need to get all of these rebinds in a single function */
createDatePickers(targets[i]);
}
} else {
ajax_response = responseText;
console_warn("uz_ajax -> no targets specified");
// Well... we have no element to target, we need to return the value instead
// of course if we return here we're going
// we probably also need to check the ajax count as this will be the last executed part before we return
}
},
complete: function () {
/* if all ajax requests have completed, unblock screen */
if(--ajax_count===0) {
$.unblockUI();
/* could use this callBack to return a value *dun dun duuuuun* */
if (options.ajaxComplete) {
options.ajaxComplete(ajax_response);
}
}
},
cache: options.cache,
dataType: options.dataType
});
}
Другой способ остановить несколько запросов AJAX - это хекнуть jQuery.active до вызова.jQuery ведет внутренний подсчет «живых» ajax-запросов, используя это свойство.- redsquare
Я посмотрю на это.
РЕДАКТИРОВАТЬ 3
Так что это результат $ ('element') .data (), но я не могу понять, что он пытается сказать, значит ли это, что есть две привязки к нему.Если да, то как мне узнать, что это за привязки и почему они не срабатывают при запуске события.
альтернативный текст http://archive.ilmv.co.uk/images/firebug-jquery-data-events.png
РЕДАКТИРОВАТЬ 4
Вот еще один скриншот проблемы, на этот раз в другом месте системы.Зеленая стрелка - это элемент, который запускает три ajax-запроса, а не в firebug, как их шесть, и что они объединяются в пару и делят метки времени до миллисекунды?
Верхние три - это те, которые еще не выполненытри нижних имеют верный результат.
альтернативный текст http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v2.png
РЕДАКТИРОВАТЬ 5
На изображении ниже показано, что происходит, когда поле выбораизменен, он запускает три различных запросов AJAX.
Мне удалось сделать немного больше отладки, и я могу сказать вам следующее:
- проблема возникает независимо от того, сколько запросов ajax запрашивает начальный элемент
- проблема возникает независимо от того, какие плагины используются
- это событие определенно вызывается только один раз
- моя оболочка uz_ajaxФункция срабатывает только один раз для каждой цели (см. консоль firebug, «Строка 29: uz_ajax ()».
- Я добавил
console.info
к каждому из обратных вызовов jquery $.ajax()
, чтобы увидеть, что и когда запускается, обратите внимание на то, что единственным обратным вызовом для огня является beforeSend()
.
альтернативный текст http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v3.png
РЕДАКТИРОВАТЬ 6
Именно тогда, после того, как @redsquare предложил через Twitter использовать console.trace()
, чтобы выяснить, "откуда запускается второе событие", как яя всегда поддерживал, я уверен, что нет двух событий, поэтому я поместил трассировку в метод $.ajax()
, вот что произошло:
альтернативный текст http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v4.png
Как вы можетевидите, я получаю проблему запроса дубликата ajax, хотя метод $.ajax()
сработал только один раз, опять же, метки времени идентичны.Я сталкивался с ошибкой в jQuery?
РЕДАКТИРОВАТЬ 7
Это происходит и в StackOverflow!
alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v5.png