2010-09-14 118 views
9

我正在使用jQuery UI選項卡,其中每個選項卡都有不同的表單。在用戶輸入各種數據後,他們提交整套選項卡,以便每個選項卡異步地發佈到服務器。這很好,我在這裏沒有問題。等待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函數做了一些處理,然後進行AJAX $ .post調用。這裏執行的最後一個$ .post('Project/SaveProject')必須等到其他帖子完成。什麼是最好的方式去做呢?

回答

14

您可以只使用.ajaxStop()事件火災時,所有其他的AJAX的POST完成,假設你正在做再沒有其他的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請求,所以它只會在所有的這些POST返回時觸發,jQuery在內部保留一個計數($.active,$.ajax.active在jQuery 1.5中)以確定同時發生的多個AJAX請求任務非常好......當它回到0時,這個事件就會發生。

這種方法可以讓你同時完成其他表單提交,並在之後儘快完成最終表單。

+0

感謝您在jQuery 1.5中提及'$ .ajax.active'! – Edgar 2011-03-29 08:00:26

2

回調:

定義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 2010-09-15 15:45:12

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()'只會在* all * AJAX請求完成時觸發,並且我在第一次運行時解除綁定,您能詳細說明這可能是一個問題嗎?此外,你的例子將無法正常工作,因爲'stack'將是一個空數組,不是'undefined' :) – 2010-09-14 21:40:51

+0

沒有看到底部的解除綁定,對此表示歉意。根據應用程序的不同,可能會出現很多ajax調用,並且在需要絕對控制的情況下,我會爲自己的工作流程創建自己的調用堆棧。當然,你的代碼也可以工作(至少如果在應用程序的早期沒有任何ajax調用,你必須在postForm方法中定義處理程序) – pederOverland 2010-09-14 21:46:46

+0

我沒有綁定處理程序,直到這批請求是發射出去:) – 2010-09-14 21:51:18

4

你總是可以讓所有的帖子同步使用類似


$.ajax({ 
    type: "POST",  
    async: false, 
    url: "", 
    ... 
當然,這不會是一樣快的

,但如果它不解決您的問題$(document).ajaxStop不是一個選項

+0

這實際上不再有效,它會返回此消息: 「主線程上的同步XMLHttpRequest已棄用,因爲它對最終用戶的體驗有不利影響。」 – di3sel 2015-12-14 07:45:18