2013-12-14 58 views
0

我已阅读了关于jQuery的Deferred对象,但我似乎无法理解它,这是我的问题,我得到以下代码:jQuery - 当所有ajax都完成时执行动作

function preprocess(form) { 
    $(form).find(".input input").each(function() { 
     var required = $(this).attr("required"); 
     var checkField = $(this).closest(".inputcontainer").children(".check"); 
     var errorField = $(this).closest(".inputcontainer").children(".errormessage"); 
     if (typeof required !== 'undefined') { 
      $(checkField).each(function() { 
       $(this).css("color", "#FFFF00"); 
       $(this).html("✘"); 
      }); 
      $(errorField).each(function() { 
       $(this).css("color", "#FFFF00"); 
       $(this).html("(Required)"); 
      }); 
     } 
     else { 
      $(checkField).each(function() { 
       $(this).css("color", "#FFFF00"); 
       $(this).html("✔"); 
      }); 
      $(errorField).each(function() { 
       $(this).css("color", "#000000"); 
       $(this).html(""); 
      }); 
     } 
    }); 

    $(form).find("datalist").each(function() { 
     var datalist = $(this); 
     callService({ 
      name: "datalist_" + $(this).attr("id"), 
      data: { }, 
      success: function(json) { 
       $(json).each(function() { 
        var html = ""; 
        $(this.options).each(function() { 
         html += "<option value='" + this.value + "'>"; 
        }); 
        $(datalist).append(html); 
       }); 
      } 
     }); 
    }); 

    $(form).find("select").each(function() { 
     var select = $(this); 
     callService({ 
      name: "select_" + $(this).attr("name"), 
      data: { }, 
      success: function(json) { 
       $(json).each(function() { 
        var html = ""; 
        $(this.options).each(function() { 
         html += "<option value='" + this.id + "'>" + this.value + "</option>"; 
        }); 
        $(select).append(html); 
       }); 
      } 
     }); 
    }); 
} 

此代码准备一种形式是准备呈现给用户,其中包括AJAX调用,这是我裹在callService({});电话,你可以看到如下:

  • 它检查输入并在字段旁边放置可能的(Required)。 (无AJAX)
  • 它动态加载<datalist><select>的选项。 (AJAX)

然后我也有以下的(简化):

function setContent(html, url) { 
    html = $.parseHTML(html); 
    $(html).filter("form").each(function() { 
     preprocess($(this)); 
    }); 
    $("#pagemain").html(html); 
} 

这得到html从AJAX调用,然后调用各种形式preprocess并更新#pagemain
但是现在数据正在显示之前preprocess已经完全完成。

问题:我怎样才能做到$("#pagemain").html(html);preprocessed,涉及AJAX过程中已经完成了吗?

回答

2

尝试:

function preprocess(form) { 
    //Your above code is omitted for brevity 
    var promises = []; 

    $(form).find("datalist").each(function() { 
     var defered = $.Deferred();//create a defered object 
     promises.push(defered.promise());//store the promise to the list to be resolved later 

     var datalist = $(this); 
     callService({ 
      name: "datalist_" + $(this).attr("id"), 
      data: { }, 
      success: function(json) { 
       $(json).each(function() { 
        var html = ""; 
        $(this.options).each(function() { 
         html += "<option value='" + this.value + "'>"; 
        }); 
        $(datalist).append(html); 
       }); 
       defered.resolve();//resolve the defered when ajax call has finished 
      } 
     }); 
    }); 

    $(form).find("select").each(function() { 
     var defered = $.Deferred();//create a defered object 
     promises.push(defered.promise());//store the promise to the list to be resolved later 
     var select = $(this); 
     callService({ 
      name: "select_" + $(this).attr("name"), 
      data: { }, 
      success: function(json) { 
       $(json).each(function() { 
        var html = ""; 
        $(this.options).each(function() { 
         html += "<option value='" + this.id + "'>" + this.value + "</option>"; 
        }); 
        $(select).append(html); 
       }); 
       defered.resolve();//resolve the defered when ajax call has finished 
      } 
     }); 
    }); 
    return promises; 
} 

setContent

function setContent(html, url) { 
    html = $.parseHTML(html); 
    var promises = []; 
    $(html).filter("form").each(function() { 
     promises = promises.concat(preprocess($(this)));//Concatenating all promises arrays 
    }); 

    $.when.apply($,promises).then(function(){// Use $.when to execute a function when all deferreds are resolved. 
     $("#pagemain").html(html); 
    }); 
} 
+0

我觉得你的代码是明确的,但是你可以张贴一些更多的解释究竟怎么了'延期的对象与我的解决方案相互作用? – skiwi

+0

@skiwi:我在代码中添加了更多评论。希望这是明确的 –

+0

好吧,我想我知道了,我也在我的网站上实现了它,它立即工作,所以+1!我会尝试为我自己制定第二个用例。 – skiwi

1

递延的CAN开始学习有点吓人,但是,像大多数事情一样,一旦灯泡亮起来,你就明白了,这很简单。创建延迟对象的简单的设置是这样的:

var defer = $.Deferred(function(dfd) { 
// do the processing you need, and then... 
// when processing is complete, make a call to... 
dfd.resolve(/* return data goes here, if required */); 
}).promise(); 

// use the deferred object like it was an ajax call 
defer.then(/* do the stuff that needed to wait */); 

因此,使用你的例子:

function setContent(html, url) { 
    html = $.parseHTML(html); 

    var defer = $.Deferred(function(dfd) { 
    $(html).filter("form").each(function() { 
     preprocess($(this)); 
    }); 

    dfd.resolve(); 
    }).promise(); 

    defer.then($("#pagemain").html(html)); 
} 
+0

我确定它是正确的,但我仍然无法完全掌握此解决方案。 @KhanhTO的解决方案可能会更加明确,但现在我可以完全掌握。 – skiwi