【ajax】關於用戶提交數據的bug記錄

【背景描述】

最近在做一個關於贈送禮物的小頁面,頁面上首先會提示當前剩餘可送的禮物數,然後提供了一個輸入框,用戶輸入要贈送的禮物數量,點擊提交到後臺完成贈送禮物,然後回到頁面刷新當前剩餘可送禮物數。

頁面如下:

這裏涉及到幾個重點:

(1)輸入框的驗證問題。

(2)兩個ajax後臺交互操作,一個是獲取剩餘可送禮物數,一個是贈送禮物的時候去後臺更新數據。

(3)點擊確定按鈕之後,上述兩塊的順序執行問題。

【問題描述】

整個頁面的流程是這樣的:

(1)頁面初始化加載[剩餘可送禮物數],ajax後臺交互取數據。

(2)必須等待[剩餘可送禮物數]加載完成以後,用戶輸入[贈送份數]。

(3)點擊[確認提交],首先驗證輸入是否合法,然後還要再刷新一遍剩餘可送禮物數,也就是這裏必須還要進行一次ajax後臺交互取數據的操作。重新刷新一遍的意義在於,防止用戶在頁面停留過久沒有刷新導致頁面顯示的數據跟後臺數據不一致,或者是有多個用戶共享這一個[剩餘可送禮物數],要保證可贈送總數的遞減保持一致。

(4)比較[贈送份數]是否超過[剩餘可送禮物數],這一步必須在[剩餘可送禮物數]加載完成之後執行。

(5)輸入驗證通過以後,執行贈送禮物的ajax操作,完成以後刷新[剩餘可送禮物數]。

小結:ajax獲取[剩餘可送禮物數] -> 用戶提交[贈送份數] -> 輸入驗證開始 -> 再刷新ajax獲取[剩餘可送禮物數] -> 比較[贈送份數]和[剩餘可送禮物數] ->驗證通過,贈送禮物ajax -> ajax刷新[剩餘可送禮物數]

遇到的問題

1. ajax獲取[剩餘可送禮物數]封裝在一個function裏 getGiftsNum(),在確認提交的function中,直接調用了getGiftsNum(),但是程序並沒有按照我們希望的順序去執行,因爲這裏的ajax默認是異步執行的,受後臺操作的複雜程度以及前臺網絡通訊等等原因造成數據返回不及時,也就是用戶提交以後還沒有得到最新的[剩餘可送禮物數]就直接進行後面的判斷了,導致出錯。

2. 嘗試過將ajax獲取[剩餘可送禮物數]的過程改成同步執行,取數據的順序正常了,但是沒法控制用戶多次點擊按鈕,造成ajax多次重複提交。

3. 要防止用戶在數據還沒有加載完全的時候,瘋狂點擊按鈕造成的ajax多次提交的問題。

【解決方案】

#1#-> 爲防止用戶多次點擊按鈕造成ajax多次提交,可以在ajax的beforeSend()和success()函數中添加按鈕關閉和按鈕打開控制,一旦開始執行ajax後臺交互,就鎖住按鈕,直至結束返回數據再打開按鈕,保證ajax在點擊按鈕之後只執行一次。

 <button type="button" class="weui-btn" id="btn_submit" οnclick="Submit()">確認贈送</button>

請注意 $("#btn_submit").attr("disabled", "disabled"); 這種方式只對button有效,對<a>標籤無效。

//打開按鈕
function openSubmit() {
    // $("#btn_submit").attr("disabled", false);
    $("#btn_submit").text("確認提交");
    $("#btn_submit").removeAttr('disabled');
    $("#btn_submit").css("background-color", "#EBA656");
}

//關閉按鈕
function disableSubmit(value) {
    // $("#btn_submit").attr("disabled", true);
    $("#btn_submit").attr("disabled", "disabled");
    $("#btn_submit").text(value);
    $("#btn_submit").css("background-color", "grey");
}

在ajax中打開按鈕和關閉按鈕的操作

function getGiftsNum() {
    $.ajax({
              data: {
                        //請求參數
                        data: request_data
                    },
              // async: false, //改成同步
              type: "post",
              url: "getGiftsNumServlet",
              dataType: "json",
              beforeSend: function () {
                    disableSubmit("正在加載...");
              },
              success: function (dataArray) {
                    // console.log(dataArray.count); //獲取後臺傳遞過來的json串
                    limitNum = dataArray.count;
                    console.log("---getPrezentsNum----limitNum: " + limitNum);

                    $("#limitNum").text(limitNum);   //數據填充到頁面上
                    openSubmit();  //打開按鈕
                },
                error: function (e) {
                    alert("ajax發生錯誤!" + e.status);
                    openSubmit();
                },
                complete: function () {
                    openSubmit();
                }
      });
}

 #2#-> 解決因爲ajax異步執行導致的無法順序執行的問題,不要直接調用函數,重寫ajax取[剩餘可贈送禮物數]的過程,在complete()函數裏去執行後面的判斷操作,避免數據還沒有取到就執行後續判斷流程了。

【完整代碼】

<body></body> 樣式用的是微信官方的WeiUI

<body>

<div class="weui-form-preview">
    <div class="weui-form-preview__hd">
        <div class="weui-form-preview__item">
            <label class="weui-form-preview__label mytitle2">剩餘的禮物數量</label>
            <em class="weui-form-preview__value" style="font-weight: bold;color: blue;" id="limitNum"></em>
        </div>
    </div>
</div>

<div>
    <div class="weui-cells__title mytitle">確認贈送份數</div>
    <div class="weui-cells">
        <div class="weui-cell">
            <div class="weui-cell__bd">
                <input class="weui-input" type="number" pattern="/(^[1-9]\d*$)/" placeholder="請輸入贈送份數" id="shareNum">
            </div>
        </div>
    </div>
</div>

<div class='demos-content-padded'>
    <button type="button" class="weui-btn weui-btn_primary mybutton" id="btn_submit" οnclick="Submit()">確認贈送</button>
</div>

</body>

<script><script>

<script type="text/javascript">

    //打開按鈕
    function openSubmit() {
        // $("#btn_submit").attr("disabled", false);
        $("#btn_submit").text("確認提交");
        $("#btn_submit").removeAttr('disabled');
        $("#btn_submit").css("background-color", "#EBA656");
    }

    //關閉按鈕
    function disableSubmit(value) {
        // $("#btn_submit").attr("disabled", true);
        $("#btn_submit").attr("disabled", "disabled");
        $("#btn_submit").text(value);
        $("#btn_submit").css("background-color", "grey");
    }

    var limitNum = -1; //最大可贈送禮物數

    //頁面初始化的時候,獲取最大可贈送禮物數
    function getGiftsNum() {
        $.ajax({
                data: {
                    data: request_data   //請求參數
                },
                // async: false, //改成同步
                type: "post",
                url: "getGiftsNumServlet",
                dataType: "json",
                beforeSend: function () {
                    disableSubmit("正在加載...");  //關閉按鈕
                },
                success: function (dataArray) {
                    // console.log(dataArray.count); //獲取後臺傳遞過來的json串
                    limitNum = dataArray.count;
                    console.log("---getGiftsNum----limitNum: " + limitNum);

                    $("#limitNum").text(limitNum);   //數據填充到頁面上
                    openSubmit();  //打開按鈕
                },
                error: function (e) {
                    alert("ajax發生錯誤!" + e.status);
                    openSubmit();  //打開按鈕
                },
                complete: function () {
                    openSubmit();  //打開按鈕
                }
        });
    }

    //----按鈕提交----
    function Submit() {
        console.log("------點擊了一次按鈕!--------");
        //----取輸入框的值進行判斷-----
        var shareNum = document.getElementById("shareNum").value;
        // --1.輸入框爲空的情況--
        if (shareNum === "") {
            alert("請輸入正確的贈送禮物份數!");
        }
        // --2.輸入框爲非正整數的情況--
        else if (!(/(^[1-9]\d*$)/.test(shareNum))) {
            alert("份數應爲正整數!");
            $("#shareNum").val("");  //清空輸入框
        }
        else {
                limitNum = -1;
                // limitNum = document.getElementById("limitNum").innerText;
                console.log("-------設置limitNum爲初始值 -1 ---------");

                //重複去後臺取數據的過程-----getGiftsNum()------
                console.log("---我在submit裏面--去後臺獲取數據------");
                $.ajax({
                    data: {
                        data: request_data   //請求參數
                    },
                    // async: false, //改成同步
                    type: "post",
                    url: "getGiftsNumServlet",
                    dataType: "json",
                    beforeSend: function () {
                        disableSubmit("正在提交中...");  //關閉按鈕
                    },
                    success: function (dataArray) {
                        // console.log(dataArray.count); //獲取後臺傳遞過來的json串
                        limitNum = dataArray.count;
                        console.log("---getGiftsNum----limitNum: " + limitNum);

                        $("#limitNum").text(limitNum);   //數據填充到頁面上
                        openSubmit();  //打開按鈕
                    },
                    error: function (e) {
                        alert("ajax發生錯誤!" + e.status);
                        openSubmit(); //打開按鈕
                    },
                    complete: function () {
                        // openSubmit();

                        console.log("limitNum已經取數完畢!");
                        console.log("shareNum: " + shareNum);
                        console.log("limitNum: " + limitNum);

                        // --3.贈送份數 > 可贈送總份數的情況--
                        if (parseInt(shareNum) > parseInt(limitNum)) {
                            alert("贈送份數不能超過當前可贈送禮物總份數!");
                            $("#shareNum").val("");  //清空輸入框
                            openSubmit();  //打開按鈕
                        }
                        // --4.輸入正常的情況,進行下一步 贈送禮物ajax--
                        else{
                                $.ajax({
                                        data: {
                                                shareNum: shareNum, //贈送份數
                                                data: request_data2 //請求參數
                                              },
                                        type: "post",
                                        url: "submitFPServlet",
                                        dataType: "json",
                                        beforeSend: function () {
                                            disableSubmit("正在送禮物中...");  //關閉按鈕
                                        },
                                        success: function (dataArray) {
                                            console.log(dataArray.result); //獲取後臺傳遞過來的json串
                                            console.log("正在贈送禮物中....");
                                            openSubmit();  //打開按鈕
                                        },
                                        error: function (e) {
                                            alert("ajax發生錯誤!" + e.status);
                                            openSubmit();    //打開按鈕
                                        },
                                        complete: function () {
                                            $("#shareNum").val("");
                                            showSubmit();   //打開按鈕
                                            console.log("贈送完成");
                                            getGiftsNum();   //刷新當前剩餘的可贈送禮物數
                                        }
                                });
                        }
                    }
                });
        }
    }

    //------頁面初始化加載--------
    $(document).ready(function () {
        getGiftsNum();  //獲取可贈送的最大禮物數
    });

</script>

關於輸入框驗證,主要分了以下4種情況

1. 輸入爲空值

2. 輸入爲負數或者0,驗證必須輸入正整數

3. 輸入值超過可贈送的最大禮物數

4. 輸入正常,進入下一步贈送禮物操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章