承諾作出的處理多個Ajax請求確實很微不足道,但是「部分形式」對GUI設計的影響可能更具挑戰性。你必須要考慮的事情,如:
- 一種形式分爲幾個部分,或每部分一種形式?
- 從一開始就顯示所有部分,或逐步顯示它們?
- 鎖定以前驗證過的部分以防止驗證後干預?
- 重新驗證每個階段的所有部分,或只是當前的部分?
- 一個整體提交按鈕還是每個部分一個?
- 應如何標記提交按鈕(以幫助用戶瞭解他所參與的過程)?
假設(這是對我的情況,但也許不是OP),我們不知道答案,所有這些問題還沒有,但他們可以體現在兩個功能 - validateAsync()
和setState()
,既其中接受stage
參數。
這使我們能夠編寫一個廣義的主例程,以滿足未知的驗證調用和各種GUI設計決策。
這一階段唯一需要的假設是形式/部分的選擇器。讓我們假設它/它們都有class="partialForm"
:
$('.partialForm').on('submit', function(e) {
e.preventDefault();
$.when(setState(1)) // set the initial state, before any validation has occurred.
.then(validateAsync.bind(null, 1)).then(setState.bind(null, 2))
.then(validateAsync.bind(null, 2)).then(setState.bind(null, 3))
.then(validateAsync.bind(null, 3)).then(setState.bind(null, 4))
.then(function aggregateAndSubmit() {
var allData = ....; // here aggregate all three forms' into one serialization.
$.post('mainurl', allData, function(result) {
console.log(result);
});
}, function(error) {
console.log('validation failed at stage: ' + error.message);
// on screen message for user ...
return $.when(); //inhibit .fail() handler below.
})
.fail(function(error) {
console.log(error);
// on screen message for user ...
});
});
這句法方便在這裏呼籲setState()
作爲然後回調雖然它的(可能)同步
樣品validateAsync()
:
function validateAsync(stage) {
var data, jqXHR;
switch(stage) {
case 1:
data = $("#form1").serialize();
jqXHR = $.ajax(...);
break;
case 2:
data = $("#form2").serialize();
jqXHR = $.ajax(...);
break;
case 3:
data = $("#form3").serialize();
jqXHR = $.ajax(...);
}
return jqXHR.then(null, function() {
return new Error(stage);
});
}
樣品setState()
:
function setState(stage) {
switch(stage) {
case 1: //initial state, ready for input into form1
$("#form1").disableForm(false);
$("#form2").disableForm(true);
$("#form3").disableForm(true);
break;
case 2: //form1 validated, ready for input into form2
$("#form1").disableForm(true);
$("#form2").disableForm(false);
$("#form3").disableForm(true);
break;
case 3: //form1 and form2 validated, ready for input into form3
$("#form1").disableForm(true);
$("#form2").disableForm(true);
$("#form3").disableForm(false);
break;
case 4: //form1, form2 and form3 validated, ready for final submission
$("#form1").disableForm(true);
$("#form2").disableForm(true);
$("#form3").disableForm(true);
}
return stage;
}
書面setState()
,將需要jQuery插件.disableForm()
:
jQuery.fn.disableForm = function(bool) {
return this.each(function(i, form) {
if(!$(form).is("form")) return true; // continue
$(form.elements).each(function(i, el) {
el.readOnly = bool;
});
});
}
正如我所說,上述validateAsync()
和setState()
只是初步的樣本。至少,你將需要:
- 割肉出局
validateAsync()
- 修改
setState()
以反映您所選擇的用戶體驗。
感謝您的時間和麻煩。我在「消化」你的答案。 –