使用jQuery回调+ AJAX条件还原元素

时间:2012-07-26 19:39:35

标签: javascript jquery html ajax

我需要根据我制作的AJAX调用来恢复对象。但是,我发现AJAX调用在函数执行完毕之前没有完成。

我尝试了各种方法,但每个方法似乎都回到了同一个异步问题 - 而且我不想进行同步调用。

在我继续确定是否应该还原之前,我如何以某种方式等待AJAX​​调用完成并且答案在那里?

$(document).ready(function() {

$.ajax
({
    type: "GET",
    url: "quizData.xml",
    dataType: "xml",
    success: function(xml)
    {
        var questionIdCount = 0;
        $(xml).find('question').each(function()
        {
            questionIdCount++;
            $("#question-container").append("<div class=\"question\" id=\"question-number-" + questionIdCount + "\">" + $(this).text() + "</div>");

            $("#question-number-" + questionIdCount).data('id', questionIdCount);

            $(".question").droppable(
            {

            }
            );

        });

        var answerIdCount = 0;
        $(xml).find('answer').each(function()
        {
            answerIdCount++;
            $("#answer-container").append("<div class=\"answer-id\" id=\"answer-number-" + answerIdCount + 
            "\">" + answerIdCount + "</div><div class=\"answer\">" + $(this).text() + "</div>");    

            $("#answer-number-" + answerIdCount).data('id', answerIdCount);

            $(".answer-id").draggable({
              revert: function(socketObj)
              {
                 if(!socketObj)
                 {
                     return true;
                 }
                 else
                 {
                    var questionId = $("#" + socketObj.attr('id')).data('id')
                    var answerId = $("#" + $(this).attr('id')).data('id');

                    return checkAnswer(questionId, answerId);
                 }


              },
              containment: "#containment-wrapper",
              scroll: true
            });


        }); 
    }
});
  $(document).ready(function() {

$.ajax
({
    type: "GET",
    url: "quizData.xml",
    dataType: "xml",
    success: function(xml)
    {
        var questionIdCount = 0;
        $(xml).find('question').each(function()
        {
            questionIdCount++;
            $("#question-container").append("<div class=\"question\" id=\"question-number-" + questionIdCount + "\">" + $(this).text() + "</div>");

            $("#question-number-" + questionIdCount).data('id', questionIdCount);

            $(".question").droppable(
            {

            }
            );

        });

        var answerIdCount = 0;
        $(xml).find('answer').each(function()
        {
            answerIdCount++;
            $("#answer-container").append("<div class=\"answer-id\" id=\"answer-number-" + answerIdCount + 
            "\">" + answerIdCount + "</div><div class=\"answer\">" + $(this).text() + "</div>");    

            $("#answer-number-" + answerIdCount).data('id', answerIdCount);

            $(".answer-id").draggable({
              revert: function(socketObj)
              {
                 if(!socketObj)
                 {
                     return true;
                 }
                 else
                 {
                    var questionId = $("#" + socketObj.attr('id')).data('id')
                    var answerId = $("#" + $(this).attr('id')).data('id');

                    return checkAnswer(questionId, answerId);
                 }


              },
              containment: "#containment-wrapper",
              scroll: true
            });


        }); 
    }
});


function checkAnswer(questionId, answerId)
{
     var ajaxAnswer;
     $.ajax
     ({
        type: "POST",
        url: "getQuizAnswers.php",
        dataType: "xml",
        data: "questionId=" + questionId + "&answerId=" + answerId,
        success: function(xml)
        {
            console.log($(xml));
            $(xml).find("answer").each(function()
            {
                //alert($(this).text());
                if($(this).text() == "true")
                    ajaxAnswer = true;
                else
                    ajaxAnswer = false;

            });             
        }
      })

    return ajaxAnswer;  
}



});


});

2 个答案:

答案 0 :(得分:0)

你已经有回电话了。

success: function(xml){
  }

是ajax请求成功完成时的回调函数。

所以从你需要的地方的某个地方打电话给checkAnswer(questionId, answerId)

如果您希望在其他ajax请求完成后调用checkAnswer,请执行以下操作:

$.when($.ajax("/page1.php"), $.ajax("/page2.php"))
  .then(checkAnswer(questionId, answerId));

jQuery.when

答案 1 :(得分:0)

斯宾塞

您应该能够使用deferred对象控制事物,并重新组织代码,以确保只有在checkAnswer内的ajax响应后才设置draggable。

我对这方面的每一个方面都没有100%的信心,但这里有:

$(document).ready(function() {
    function setDraggable(revert) {
        $(".answer-id").draggable({
            revert: revert
            containment: "#containment-wrapper",
        });
    }
    $.ajax({
        type: "GET",
        url: "quizData.xml",
        dataType: "xml",
        success: function(xml) {
            var questionIdCount = 0;
            $(xml).find('question').each(function() {
                questionIdCount++;
                $("#question-container").append("<div class=\"question\" id=\"question-number-" + questionIdCount + "\">" + $(this).text() + "</div>");
                $("#question-number-" + questionIdCount).data('id', questionIdCount);
                $(".question").droppable({});
            });
            var answerIdCount = 0;
        $(xml).find('answer').each(function() {
            answerIdCount++;
            $("#answer-container").append("<div class=\"answer-id\" id=\"answer-number-" + answerIdCount + "\">" + answerIdCount + "</div><div class=\"answer\">" + $(this).text() + "</div>");
            $("#answer-number-" + answerIdCount).data('id', answerIdCount);
            if(socketObj) {
                var questionId = $("#" + socketObj.attr('id')).data('id')
                var answerId = $("#" + $(this).attr('id')).data('id');
                $.when(checkAnswer(questionId, answerId)).done(function() {
                    setDraggable(true);
                }).fail(function() {
                    setDraggable(false);
                });
            }
            else {
                setDraggable(true);
            }
            scroll: true
        });
        }
    });
    function checkAnswer(questionId, answerId) {
        var ajaxAnswer = true;//remains true unless an incorrect answer is received
        var def =  new $.Deferred();
        $.ajax({
            type: "POST",
            url: "getQuizAnswers.php",
            dataType: "xml",
            data: {"questionId":questionId, "answerId":answerId},
            success: function(xml) {
                console.log($(xml));
                $(xml).find("answer").each(function() {
                    ajaxAnswer = ajaxAnswer && ($(this).text() == "true");
                });
                if(ajaxAnswer) 
                    def.resolve();//success
                else 
                    def.reject();//failure
            },
            error: function(){
                def.reject();//assume failure if ajax fails
            }
        });
        return def;//IMPORTANT!!
    }
});

这有点棘手,需要解释......

checkAnswer开始,您会看到它现在返回deferred object,在不久的将来某些时候(“getQuizAnswers.php”响应)会被解析或拒绝。

回到.find('answer').each(...)循环,您将看到代码已由内到外翻转。现在,不是在draggabe中调用checkAnswer(),而是设置draggable以响应checkAnswer(更具体地说,响应checkAnswer的延迟被解决或拒绝)。

由于需要在多个条件下设置可拖动,因此可拖动代码已移至实用功能中,从而避免重复。您可能需要将更多参数传递给此函数以更具体地控制其行为(特别是jQuery选择器)。

这可能需要调整/调试,可能有一个更简单的方法,但这是立即想到的。