簡體   English   中英

等待form.submit()/ POST完成

[英]Wait for form.submit() / POST to complete

我在這里陷入了一個非常奇怪的境地。 解釋起來很復雜,但我會盡我所能。

問題的詳細解釋:

在每個頂部導航點擊(綠色甜甜圈/圓圈)或下一個按鈕,我必須提交表格,如果它存在並且有效。 如果無效,form.valid()會觸發驗證錯誤,返回false會停止任何進一步的傳播。 這個設置完美無缺,直到我注意到一個不太持久的奇怪行為。 特別是,我的第三個選項卡上的表單非常重要。 當我點擊下一個按鈕時,它應該通過相同的過程:檢查現有表格,如果有效,則提交。 提交調用POST操作方法,當post完成時,獲取下一個選項卡的視圖。 它的工作方式類似於5/10次,但在其他時候,GET在POST之前執行,這會導致下一頁加載不完整的數據。 當我將斷點調試時,我看到GET在當前選項卡的POST之前執行下一個選項卡。

用戶界面說明:

我有一個UI,頂部有4個導航<a>按鈕 - 中間有一個總是一個表單 - 而在底部我有上一頁和下一頁按鈕。

在此輸入圖像描述

使用Ajax.BeginForm在MVC中構造表單

對於頂部的每個Nav鏈接<a>元素,我有一個JavaScript函數

var LoadTabs = function (e, arg) {  
    // This is to validate a form if one of the top links is clicked and form has incomplete fields...
    if (arg !== "prev" && arg !== "next") {
        if (!window.ValidateForm(false)) return false;
    }

    var url = $(this).attr('data'); // this contains link to a GET action method
    if (typeof url != "undefined") {
        $.ajax(url, { context: { param: arg } }).done(function (data) {                
            $('#partialViewContainer').html(data);
        });
    }
}

上面的這個函數綁定到頁面加載的每個頂部鏈接。

$('.navLinks').on('click', LoadTabs);

我的下一個和上一個按鈕基本上觸發了點擊事件,即LoadTabs功能。

$('button').on('click', function () { 
        if (this.id === "btnMoveToNextTab") {
            if (!window.ValidateForm(true)) return false;                

            $.ajax({
                url: url,
                context: { param: 'next' },
                method: "GET",
                data: data,
                success: function(response) {
                    if (typeof response == 'object') {
                        if (response.moveAhead) {
                            MoveNext();
                        }
                    } else {
                        $('#mainView').html(response);
                    }
                    ScrollUp(0);
                }
            });
        } 

        if (this.id === "btnMoveToPreviousTab") {
            MoveBack();
        }
        return false;
    });


MoveNext() Implementation is as below:

function MoveNext() {        
    var listItem = $('#progressbarInd > .active').next('li');        

    listItem.find('.navLink').trigger('click', ['next']);
    ScrollUp(0);
}

問題是,由於某些原因,導航鏈接3處於活動狀態並且我點擊下一步按鈕 - 而不是首先通過form.submit()發布表單 - 導航4被觸發 - 因此導航4的GET在導航的形式POST之前運行3。

我的ValidateForm方法基本上只是檢查表單是否存在且有效然后是Submit,否則返回false。 如下:

function ValidateForm(submit) {

    var form = $('form');

    // if form doesn't exist on the page - return true and continue
    if (typeof form[0] === "undefined") return true;

    // now check for any validation errors
    if (submit) {
        if (!$(form).valid()) {                
            return false;
        } else {
            $(form).submit();
        }
    } 
    else {
        return true;
    }

    return true;
}

我猜測form.submit確實會被觸發,但由於提交需要更長時間才能完成,因此繼續使用按鈕onclick事件中的下一個代碼塊。

我首先想到這是一個服務器端問題,因為在POST我用一些循環保存了一大塊數據,並且任何代碼塊都是流程繁重的我有這個部分

var saveTask = Task.Factory.StartNew(() => ControllerHelper.SomeMethod(db, model)); Task.WaitAll(saveTask);

WaitAll將等待並暫停執行,直到SomeMethod完成執行。 我不知道如何在JavaScript中鎖定進程並等待它完成執行。 因為我認為如果我可以以某種方式鎖定ValidateForm中的form.submit()直到它完成處理..通過回調方法也許......

如果有人能把我指向正確的方向,我將非常感謝你的幫助。 如果您需要更多信息,請告訴我我很樂意提供!

Ajax是異步的,使用Ajax.BeginForm()表單提交正在使用ajax。 發生的事情是當你點擊'下一步'按鈕時,它會觸發$('button').on('click', function () { code:

  1. 你調用ValidateForm()函數(並假設它是有效的), $(form).submit(); 代碼行開始制作ajax POST
  2. 代碼進展到最終return true; ajax調用正在執行時行。
  3. 因為ValidateForm()函數返回true,現在啟動$.ajax GET調用,但此時ValidateForm()函數中的ajax POST可能尚未執行,導致GET方法返回無效數據

您需要更改代碼,以便在POST方法調用完成后進行GET調用。 而且由於你在代碼中使用了$.ajax()方法,並且$.ajax()為你提供了更大的靈活性,所以似乎沒有必要使用Ajax.BeginForm() (以及包含jquery.unbtrusive-ajax.js的額外開銷) jquery.unbtrusive-ajax.js腳本)。 您還應該處理表單.submit()函數(如果您不希望'Next'按鈕成為表單中的提交按鈕,您可以在按鈕.click()處理程序中觸發.submit()事件。 )

$(document).on('submit', 'form', function(e) {
    e.preventDefault(); // cancel default submit
    var form = $(this);
    if (!form.valid()) {
        return; // will display the validation errors
    }
    .... // get the relevant urls to the GET and POST methods etc
    $.post(postUrl, form.serialize(), function(data) {
        .... // not clear if your [HttpPost] method returns anything
    }).done(function() {
        $.get(getUrl, someData, function(response) {
            .... // Update the DOM with the next form?
            .... // Re-parse the validator for client side validation
        }
    }).fail(function() {
        .... // code that you might run if the code in the [HttpPost] method fails
    });
});

您還應該考慮在[HttpPost]方法中返回相應的“下一個”視圖,這樣您就不需要再次回調服務器來獲取它。

還值得閱讀Deferred Object文檔以及$.when()$.then()等的使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM