2014-09-04 3 views
1

jquery.getJSON 내에서 jquery.each() 기능을 사용할 때 문제가 있습니다. 이 경우에는 내 코드에서 다루는 두 가지 유형의 요소가 있습니다. "소스"와 "스트림" 먼저 소스를 가져 와서 반복하고 그 중 아코디언 헤더를 생성하려면 getJSON을 사용하고 싶습니다. 그런 다음 해당 "소스"각각에 대해 다시 해당 소스의 ID와 함께 getJSON을 사용하여 해당하는 "스트림"을 얻습니다. 그런 다음 해당 소스를 소스 아코디언 본문에 추가하여 소스별로 정렬 된 모든 스트림의 목록을 가져옵니다.

하지만 JSON을 얻는 동안 내 프로 시저의 다음 명령문이 이미 실행 된 것 같습니다. 기본적으로 큰 HTML String을 동적으로 만들고 jQuery를 사용하여 요소에 추가하면 String은 필요한 모든 데이터를 얻지 못합니다.

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에 추가되기 전에 반환됩니다.

이미 내 $.getJSON 통화 모두에 async = false$.ajax$.getJSON을 변경 시도,이 문장은 내가 그들이 원하는 순서대로 실행되지 않는 문제를 해결하기 위해 보이지만 그것은 끔찍하게 느린과 undefined를 반환 어쨌든 웬일인지 ..

어떤 제안이라도? 정말 바보 같은 것을 놓치고 있습니까?

+0

서버에 html을 생성하는 것이 좋습니다. 이후 루프에서 클라이언트 끝에서 사용자 입력을 필요로하지 않기 때문에. 따라서 서버에서 html 문자열을 생성하는 것이 더 좋을 것입니다. 이보다 훨씬 빨라질 것입니다. 또는 어떤 경우 에든 디자인이 필수적이라면 option cache : false 및 async : false를 사용하여 $ .ajax를 시도하십시오. – Priyank

+1

녹아웃 및 각도와 같은 적절한 mvvm 라이브러리가있을 때 jQuery에서이 작업을 시도해 보는 것이 미친 것입니다. – andrew

답변

1

는 HTML 문자열 맞습니다 DOM을

에 추가되기 전에 반환하지 않습니다 getAccordionBody() 함수를 보인다. returning the response (html3) from ajax의 길에 결함이 있습니다. done 핸들러에서 return을 사용할 수 없습니다.

그러나 약속을 사용하여이 문제를 해결할 수 있습니다. 모든 기능은 쉽게 체인되도록 약속을 반환하고 then은 데이터를 변환하고이를위한 새로운 약속 가져 오는 데 사용됩니다 : 먼저 ""getAccordionPart "및 필요한 모든 것을 수집해야

$.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

+0

[약속을 숙지하십시오] (https://github.com/kriskowal/q/wiki/General-Promise-Resources) 물론 :-) – Bergi

0

동기화 호출을 사용하는 대신 지연된/약속하는 패턴 (http://api.jquery.com/deferred.promise/)을 사용할 수 있습니다.

  • 아코디언 생성 기능에서 약속을 반환해야합니다.
  • 생성 아코디언 함수 호출을 큐에 넣어야합니다.
  • 그런 다음 약속이 해결되면 순차적으로 추가 비즈니스를 수행하십시오.
0

을 getAccordionBody "(예 : encodeURIComponent (json.elementId))를 전역 배열로 가져옵니다.like :

이 컬렉션에 대해 반복하고 모든 전역 변수에서 이러한 ID의 accordian 본문에 대한 모든 데이터를 수집합니다.

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; 
} 
부르심도 변경됩니다

:

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을 변경

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의 저 작은 변화 할

$.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 
});