如何在 jquery 中使用延迟执行方法

How to use Delay for method execution in jquery

我在其中一个表格中使用 jquery。在单击提交按钮时,我调用了一个函数 QuoteDetailValidation()。我在其中验证字段。但是在验证这些字段之后,我尝试获取所有具有 errorActive class 的字段。但不幸的是我无法得到它。

查看我的代码

$('#saveQuote').on('click', function(event) {

    var descriptionData1 = $('input[name=\"QuoteDetail[description][]\"]');
    QuoteDetailValidation(descriptionData1);

    var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length;

    alert(selectors);
    return false;
});

function QuoteDetailValidation(descriptionData1) {

    for (var i = 0; i < descriptionData1.length; i++) {

        var id = descriptionData[i].id;
        var value = descriptionData[i].value;
        var costid = costData[i].id;
        var costValue = costData[i].value;

        $.ajax({
            type: 'GET',
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {
                var obj = $.parseJSON(data);
                var cost = obj.cost;
                var desc = obj.desc;

                if (desc != '' || cost != '') {

                    if (cost != '') {

                        $('#' + costid).addClass('errorActive');
                        $('#' + costid).prev().addClass('error');
                        $('#' + costid).next().remove();
                        $('#' + costid).after(cost);
                        $('#' + costid).parent().removeClass('success');
                        $('#' + costid).parent().addClass('error');

                    }

                }
            },
            error: function(data) {
                alert('Your data has not been submitted..Please try again');
            }


        });
    }
}

现在会发生什么,当出现错误时 QuoteDetailValidation() 附加 errorActive class 到字段。

通过 var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length; 我尝试获取具有 errorActive class 的字段的长度。但在 selectors 的警报下,它总是给出 0。但是当我在得到所有 errorActive Class 之前提醒某些事情时,然后提醒 selectors 给我完美的计数。我认为在获得 class errorActive 之前由于警报而存在延迟。以便它给我计数。如何使用它。请任何帮助。提前致谢。

您需要在 QuoteDetailValidation 方法的成功回调中执行此操作,因为 $.ajax 运行异步并且在调用该方法后仍未完成。

    $.ajax({
        type: 'GET',
        url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
        data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
        success: function(data) {
            var obj = $.parseJSON(data);
            var cost = obj.cost;
            var desc = obj.desc;

            if (desc != '' || cost != '') {
                if (cost != '') {
                    $('#' + costid).addClass('errorActive');
                    $('#' + costid).prev().addClass('error');
                    $('#' + costid).next().remove();
                    $('#' + costid).after(cost);
                    $('#' + costid).parent().removeClass('success');
                    $('#' + costid).parent().addClass('error');
                }
            }
            // Here you know that the elements will have the necessary classes.
            var selectors = $('#quote-quoteItems-form .errorActive').length;
            alert(selectors);
        },
        error: function(data) {
            alert('Your data has not been submitted..Please try again');
        }
    });

您可以确定正确初始化选择器所需的确切延迟。我们添加的任何延迟都将是假设,并且对于某些场景来说可能很短 在您的 ajax 请求

中使用下面的一个选项
async: false

如下所示:-

$.ajax({
            type: 'GET',
            async: false,
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {}});

将 async 设置为 false 意味着您正在调用的语句必须先完成,然后才能调用函数中的下一条语句。如果您设置 async: true(这是默认值),那么该语句将开始执行,并且无论异步语句是否已完成,都会调用下一条语句。 Helpful question

但我仍然会建议您将选择器部分移动到成功的 ajax 中,如下所示:-

$.ajax({
            type: 'GET',
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {
                var obj = $.parseJSON(data);
                var cost = obj.cost;
                var desc = obj.desc;

                if (desc != '' || cost != '') {

                    if (cost != '') {

                        $('#' + costid).addClass('errorActive');
                        $('#' + costid).prev().addClass('error');
                        $('#' + costid).next().remove();
                        $('#' + costid).after(cost);
                        $('#' + costid).parent().removeClass('success');
                        $('#' + costid).parent().addClass('error');

                    }

                }
var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length;
alert(selectors);
//some logice here or move the above in some function and call it here

            },
            error: function(data) {
                alert('Your data has not been submitted..Please try again');
            }


        });

或使用call back functions.

更新: 尝试类似下面的操作它将保持异步为真并将计数逻辑保持在 $.ajax.

之外
function QuoteDetailValidation(descriptionData1,submitFormOrAddError) {

    for (var i = 0; i < descriptionData1.length; i++) {

        var id = descriptionData[i].id;
        var value = descriptionData[i].value;
        var costid = costData[i].id;
        var costValue = costData[i].value;

        $.ajax({
            type: 'GET',
            url: "<?php echo Yii::app()->createUrl('QuoteData/validatedata'); ?>",
            data: 'descvalue=' + value + '&Descname=description&costValue=' + costValue + '&costName=cost&descId=' + id + '&costId=' + costid,
            success: function(data) {
                var obj = $.parseJSON(data);
                var cost = obj.cost;
                var desc = obj.desc;

                if (desc != '' || cost != '') {

                    if (cost != '') {

                        $('#' + costid).addClass('errorActive');
                        $('#' + costid).prev().addClass('error');
                        $('#' + costid).next().remove();
                        $('#' + costid).after(cost);
                        $('#' + costid).parent().removeClass('success');
                        $('#' + costid).parent().addClass('error');

                    }

                }
                submitFormOrAddError(data);
            },
            error: function(data) {
                alert('Your data has not been submitted..Please try again');
            }


        });
    }
}

这样称呼它:

$('#saveQuote').on('click', function(event) {

    var descriptionData1 = $('input[name=\"QuoteDetail[description][]\"]');
    QuoteDetailValidation(descriptionData1);


    QuoteDetailValidation(descriptionData1,function(output){
            // here you use the output
            var selectors = document.querySelectorAll('#quote-quoteItems-form .errorActive').length; //This line is excuted only after call completes
            alert(selectors);
            //form submit here if error is zero.
        });

        alert("hii");//this  line is executed without waiting for above call..
        return false;
});