2014-09-04 132 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 
});