2010-09-14 3 views
9

Я использую вкладки пользовательского интерфейса jQuery, где каждая вкладка имеет на ней другую форму. После того, как пользователь вводит различные фрагменты данных, они отправляют весь набор вкладок, чтобы каждая вкладка асинхронно отправляла на сервер. Это хорошо работает, и у меня здесь нет проблем.Ждать вызова AJAX (POST) для завершения

Однако, когда я сталкиваюсь с проблемой, последняя форма, которую я отправляю, должна произойти ПОСЛЕ всех остальных сообщений. Общая идея такова:

postForm(0, "#Form1"); 
postForm(1, "#Form2"); 
postForm(2, "#Form3"); 
postForm(3, "#Form4"); 
$.post('Project/SaveProject', function (data) { 
    $('<div class="save-alert">The current project has been saved.</div>') 
    .insertAfter($('#tabs')) 
    .fadeIn('slow') 
    .animate({ opacity: 1.0 }, 3000) 
    .fadeOut('slow', function() { 
     $(this).remove(); 
    }); 
}); 

Функция postForm делает немного обработки, а затем делает .post вызов AJAX $. Последний $ .post, выполняемый здесь (в Project/SaveProject), должен дождаться завершения этих других сообщений. Каков наилучший способ сделать это?

ответ

14

Вы можете просто использовать .ajaxStop() событие, которое срабатывает, когда все другие посты AJAX закончить, если вы делаете никакой другой AJAX не работает, то, как это:

postForm(0, "#Form1"); 
postForm(1, "#Form2"); 
postForm(2, "#Form3"); 
postForm(3, "#Form4"); 
$(document).ajaxStop(function() { 
    $.post('Project/SaveProject', function (data) { 
    $('<div class="save-alert">The current project has been saved.</div>') 
    .insertAfter($('#tabs')) 
    .fadeIn('slow') 
    .animate({ opacity: 1.0 }, 3000) 
    .fadeOut('slow', function() { 
     $(this).remove(); 
    }); 
    }); 
    $(this).unbind('ajaxStop'); 
}); 

.ajaxStop() пожары, когда все Запросы AJAX, которые выполняются в полном объеме, так что он срабатывает только тогда, когда все из этих POSTs вернулись, jQuery хранит счет внутри ($.active, $.ajax.active в jQuery 1.5), чтобы определить, сколько одновременных AJAX повторно квесты выдающиеся ... когда он возвращается к 0, это событие срабатывает.

Этот подход позволяет одновременно выполнять другие формы и выполнять окончательную форму как можно скорее.

+0

Спасибо, что упомянул '$ .ajax.active' в jQuery 1.5! – Edgar

2

Callbacks:

Определение postForm взять обратный вызов:

function postForm(ind, id, callback) 
{ 
    // ... 
    $.post(url, function() 
    { 
    // ... 
    callback(); 
    }); 
} 

Затем сделать что-то вроде ниже. Вы можете использовать рекурсию, чтобы записать ее менее жестко, что может быть особенно полезно, если есть больше форм.

postForm(0, "#Form1", function() 
{ 
    postForm(1, "#Form2", function() 
    { 
     postForm(2, "#Form3", function() 
     { 
      postForm(3, "#Form4", function() 
      { 
       $.post('Project/SaveProject', function (data) { 
        $('<div class="save-alert">The current project has been saved.</div>') 
         .insertAfter($('#tabs')) 
         .fadeIn('slow') 
         .animate({ opacity: 1.0 }, 3000) 
         .fadeOut('slow', function() { 
          $(this).remove(); 
         }); 
       }); 
      }); 
     }); 
    }); 
}); 
+0

Спасибо за ответ. Я изначально считал это, но потом решил, что это слишком сложно для работы. (+1) – JasCav

0

Проблема с ajaxStop заключается в том, что он будет срабатывать каждый раз, когда будет выполнен любой ajax. Альтернатива реализует свой собственный стек метод, как это:

var stack = [] 
postForm(var1, var2){ 
    stack.push(1); 
    //Do postForm stuff 
    stack.pop(); 
    if (stack == undefined){ 
     //Call the last post method 
    } 
} 
postForm(0, "#Form1"); 
postForm(1, "#Form2"); 
postForm(2, "#Form3"); 
postForm(3, "#Form4"); 
$.post('Project/SaveProject', function (data) { 
    $('<div class="save-alert">The current project has been saved.</div>') 
    .insertAfter($('#tabs')) 
    .fadeIn('slow') 
    .animate({ opacity: 1.0 }, 3000) 
    .fadeOut('slow', function() { 
     $(this).remove(); 
    }); 
}); 
+0

'ajaxStop()' будет запускаться только в том случае, если все * AJAX-запросы завершены, и я отключаю его при первом запуске, можете ли вы рассказать о том, как это может быть проблемой? Кроме того, ваш пример не будет работать, потому что 'stack' будет пустым массивом, а не' undefined' :) –

+0

Не видел, чтобы отвязался внизу, извинитесь за это. В зависимости от приложения может появиться много вызовов ajax, и в ситуациях, когда вам необходим абсолютный контроль, я бы сделал свой собственный стек вызовов для своего рабочего процесса.Конечно, ваш код также работает (по крайней мере, если раньше в приложении не было никаких вызовов ajax, где вам нужно было бы определить обработчик в методе postForm) – pederOverland

+0

Я не привязываю обработчик, пока эта партия запросов не будет уволен либо :) –

4

Вы всегда можете сделать все сообщения синхронным, используя нечто вроде


$.ajax({ 
    type: "POST",  
    async: false, 
    url: "", 
    ... 

конечно это не было бы так быстро, но это не решает проблему, если $ (document) .ajaxStop не является опцией

+0

Это больше не работает, оно возвращает это сообщение: «Синхронный XMLHttpRequest в основной теме устарел из-за его пагубных последствий для конечных пользователей». – di3sel

Смежные вопросы