我正在尝试进行嵌套的ajax调用,但迭代不起作用:假设我有2家公司,公司编号1有2个联系人,公司编号2有3个联系人。我无法弄清楚为什么,但下面给出的代码显示了两个公司名称后跟五个联系人名称:它不是嵌套....
<script type="text/javascript">
$(function () {
$('#searchbutton').bind('click', function (event) {
$("#result > h4, #result > p").remove();
$("<p>Loading...</p>").appendTo($("#result"));
$.ajax({
type: "GET",
dataType: "jsonp",
cache: true,
url: "http://localhost/archilab/archilabdirectory.svc/",
data: ("tag=" + $("#searchstring").val()),
success: function (companies) {
$("#result > p").remove();
$.each(companies, function () {
var outer = this;
$("<h4>", { text: outer.Name + " (" + outer.Perimeter + ")" }).hide().appendTo($("#result")).show(4000, function () {
$.ajax({
type: "GET",
dataType: "jsonp",
cache: true,
url: "http://localhost/archilab/archilabdirectory.svc/" + outer.Name + "/contacts/",
success: function (contacts) {
$(contacts).each(function () {
$("<p>", { text: this.FirstName + " " + this.LastName }).hide().appendTo($("#result")).show();
});
}
})
});
});
}
});
})
});
</script>
答案 0 :(得分:1)
您确实意识到您的$.ajax
电话是异步的,对吧?这each
:
$.each(companies, function () { /* ... */ });
将添加<h4>
,启动异步$.ajax
调用,然后重复companies
中的下一个条目。 AJAX调用几乎肯定需要比$.each
更长的时间来完成,因此它将生成公司名称<h4>
,然后AJAX调用将完成并添加<p>
。无法保证<p>
甚至可以按正确的顺序添加。
如果您需要按特定顺序执行某些操作,那么您必须在$.ajax
来电中添加async: false
。
更新:我需要比评论提供的更多空间。不,这不是我的最后一个定理。
您可以将<h4>
内容推送到内部成功处理程序中,但这仍然会让您对订购问题持开放态度(即第二次AJAX调用可能在第一次之前完成)。我认为最简单的方法是在<div>
和<h4>
元素周围添加包含ID属性的包装<p>
,这样可以为.append
提供一个简单的目标呼叫;有点像这样:
$.each(companies, function() {
var $wrapper_hack = $('<div/>');
$('#result').append($wrapper_hack);
add_content($wrapper_hack, outer);
});
// And elsewhere...
function add_content($wrapper_hack, outer) {
$("<h4>", {
text: outer.Name + " (" + outer.Perimeter + ")"
}).hide().appendTo($wrapper_hack).show(4000, function () {
$.ajax({
/* ... */
success: function(contacts) {
/* Build your <p> and append it to $wrapper_hack */
}
});
});
}
我们的想法是将内容附加到右侧<h4>
附加的内容而非附加到#result
;然后,所有内容都将以正确的顺序显示,因为您已在HTML元素嵌套中嵌入了正确的顺序。您需要add_content
作为单独的函数来正确地将$wrapper_hack
和outer
本地化到所需的上下文,从而避免通常的闭包问题。