2014-09-04 125 views
1

jquery.getJSON中使用jquery.each()函数时出现问题。 在这种情况下,我在代码中处理的元素有两种类型。 “Sources”和“Streams” 我想使用getJSON首先获取源代码,对它们进行迭代并生成手风琴标头。然后,对于这些“来源”中的每一个,我再次使用getJSON与该来源的ID来获取它的相应“流”。然后,我将这些流添加到它的源手风琴体中,以获取所有流的列表,并根据它们的来源进行排序。

但是,当我得到JSON时,我的过程中的下一个语句已经被执行。由于我基本上是动态构建一个大的HTML字符串并使用jQuery将其添加到元素,因此字符串不会获取所需的所有数据。

的代码如下:

var html1 = "<div class='panel-group' id='manageAccordion'>"; 
$.getJSON(url, function(data){ 
    $.each(data, function(i, json){ 
     html1 += getAccordionPart(...); //creates the accordion for the given source 
    }); 

}).done(function(){ 
    html1 += "</div>"; 
    $('#elementList').html(html); 
}); 

function getAccordionPart(id, parent, count, json){ 
    //new string html2 is created and a bunch of stuff added 
    //... 
    html2 += "...."; 
    html2 += getAccordionBody(json); 
    html2 += "</div></div></div></div>"; 
    return html2 
} 

function getAccordionBody(json){ 
//new string "html3" gets created 
//... 

var url = standardUrl + "sources/" + encodeURIComponent(json.elementId) + "/streams"; 
$.getJSON(url, function(data) { 
    $.each(data, function(i, json) { 
     html3 += "<li class='list-group-item'>"; 
     html3 += json.name; 
     html3 += "</li>"; 
    }); 

}).done(function(){ 
    html3 += "</ul>"; 
    return html3; 
}); 

}

我专门与最终是手风琴标头,在它的身上, 因为它似乎是getAccordionBody()功能没有按”“不确定”在html字符串被添加到DOM之前返回。

我已经尝试过与async = false改变$.getJSON$.ajax,在我的两个$.getJSON调用,这似乎解决了报表不我希望他们的顺序执行的问题,但它是可怕的缓慢和返回undefined无论如何由于某种原因..

有什么建议吗? 我错过了一些真正愚蠢的东西吗?

+0

这将是很好的生成服务器上的html。因为它不需要客户端在循环中输入任何用户输入。因此,在服务器上生成该html字符串将会更好。这将更快。或者,如果您的设计是强制性的,那么请尝试带有选项缓存的$ .ajax:false和async:false。 – Priyank 2014-09-04 10:29:24

+1

这是疯狂的尝试,并在jQuery做这个东西,当有适当的mvvm库像淘汰赛和角 – andrew 2014-09-04 10:33:52

回答

1

似乎getAccordionBody()函数之前的HTML字符串被添加到DOM

这是正确的不会返回。你的方式returning the response (html3) from ajax是有缺陷的 - 你不能从done处理程序return

但是,您可以通过使用承诺来解决此问题。每个函数返回一个承诺,使他们很容易链接,并then来转换数据,并得到一个新的承诺:

$.getJSON(url).then(function(data){ 
    return $.when.apply($, $.map(data, function(i, json){ 
     return getAccordionPart(…); //creates the accordion for the given source 
    }).then(function() { 
     var html1 = "<div class='panel-group' id='manageAccordion'>"; 
     html1 += Array.prototype.join.call(arguments, "\n"); 
     html1 += "</div>"; 
     return html1; 
    }); 
}).done(function(html){ 
    $('#elementList').html(html); 
}); 

function getAccordionPart(id, parent, count, json){ 
    return getAccordionBody(json).then(function(result) { 
     var html2 = "…"; //new string html2 is created and a bunch of stuff added 
     html2 += result; 
     html2 += "</div></div></div></div>"; 
     return html2; 
    }); 
} 

function getAccordionBody(json) { 
    var url = standardUrl + "sources/" + encodeURIComponent(json.elementId) + "/streams"; 
    return $.getJSON(url).then(function(data) { 
     var html3 = "…"; //new string "html3" gets created 
     $.each(data, function(i, json) { 
      html3 += "<li class='list-group-item'>"; 
      html3 += json.name; 
      html3 += "</li>"; 
     }); 
     html3 += "</ul>"; 
     return html3; 
    }); 
} 
+0

谢谢,我得到它的工作,即使我还没有完全明白它 – Cuddl3s 2014-09-04 13:01:01

+0

你会想[熟悉承诺] (https://github.com/kriskowal/q/wiki/General-Promise-Resources)当然是:-) – Bergi 2014-09-04 13:21:54

0

与其使用同步呼叫,您可以使用延迟/承诺模式 - http://api.jquery.com/deferred.promise/

  • 您将需要从生成手风琴函数返回承诺。
  • 您需要排队生成手风琴函数调用。
  • 然后在解决承诺时按顺序执行附加业务。
0

你必须先收集这是需要“getAccordionPart”和“一切getAccordionBody“(例如:encodeURIComponent(json.elementId))全局数组中。例如:

var arrIds = []; 

$.getJSON(url, function(data){ 
$.each(data, function(i, json){ 
    arrIds.push(encodeURIComponent(json.elementId))//collect everything which is required for "getAccordionPart" and "getAccordionBody" 
}); 

然后迭代此集合并收集这些ids在所有全局变量中的所有数据。

var bodyData = {}; 
$.each(arrIds, function(){ 
var url = standardUrl + "sources/" + this + "/streams"; 
$.getJSON(url, function(data) { 
    bodyData[this] = data;//collect all the Data for accordian body of these ids 
}}); 

而且做getAccordionPart像痘痘变化:

function getAccordionPart(id, parent, count, /*json*/ elementId){ 
//new string html2 is created and a bunch of stuff added 
//... 
html2 += "...."; 
html2 += getAccordionBody(elementId); 
html2 += "</div></div></div></div>"; 
return html2 
} 

也改变getAccordionBody像:

function getAccordionBody(/*json*/ elementId){ 
//new string "html3" gets created 
//... 

var data = bodyData[elementId]; 
    $.each(data, function(i, json) { 
     html3 += "<li class='list-group-item'>"; 
     html3 += json.name; 
     html3 += "</li>"; 
    }); 
html3 += "</ul>"; 
    return html3; 
} 

您的电话也随之发生变化:

$.each(arrIds , function(){ 
    html1 += getAccordionPart(,,,this); //creates the accordion for the given source 
}); 

你最终的代码将是l是:

var arrIds = []; 

$.getJSON(url, function(data){ 
$.each(data, function(i, json){ 
    arrIds.push(encodeURIComponent(json.elementId))//collect everything which is required for "getAccordionPart" and "getAccordionBody" 
}); 

var bodyData = {}; 
$.each(arrIds, function(){ 
var url = standardUrl + "sources/" + this + "/streams"; 
$.getJSON(url, function(data) { 
    bodyData[this] = data;//collect all the Data for accordian body of these ids 
}}); 

function getAccordionPart(id, parent, count, /*json*/ elementId){ 
    //new string html2 is created and a bunch of stuff added 
    //... 
    html2 += "...."; 
    html2 += getAccordionBody(elementId); 
    html2 += "</div></div></div></div>"; 
    return html2 
    } 

function getAccordionBody(/*json*/ elementId){ 
//new string "html3" gets created 
//... 

var data = bodyData[elementId]; 
    $.each(data, function(i, json) { 
     html3 += "<li class='list-group-item'>"; 
     html3 += json.name; 
     html3 += "</li>"; 
    }); 
html3 += "</ul>"; 
    return html3; 
} 

$.each(arrIds , function(){ 
    html1 += getAccordionPart(,,,this); //creates the accordion for the given source 
});