2014-09-04 3 views
1

У меня проблема при использовании функции jquery.each() в пределах jquery.getJSON. В этом случае в моем коде есть два типа элементов. «Источники» и «Потоки» Я хочу использовать getJSON, чтобы сначала получить источники, перебрать их и создать из них заголовок гармошки. Затем для каждого из этих «источников» я снова использую getJSON с идентификатором этого источника, чтобы получить соответствующие «потоки». Затем я добавляю эти потоки к своим источникам аккордеона, чтобы получить список всех потоков, отсортированных по их источникам.

Но, кажется, пока я получаю JSON, следующие операторы в моей процедуре уже выполнены. Поскольку я в основном динамически создаю большую строку HTML и добавляю ее к элементу с помощью 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() Безразлично» t до того, как строка html добавится в DOM.

я уже попытался изменить $.getJSON к $.ajax с async = false, на оба моих $.getJSON звонков, это, кажется, чтобы решить эту проблему, что операторы не выполнять в порядке, я хочу их, но это ужасно медленно и возвращает неопределенное значение в любом случае почему-то ..

Любые предложения? Я пропустил что-то действительно глупое?

+0

Будет полезно сгенерировать html на сервере. Поскольку доза не требует ввода пользователем с конца клиента в цикле. Поэтому лучше создать такую ​​строку html на сервере. Это будет намного быстрее. В любом случае, если ваш проект является обязательным, попробуйте $ .ajax с кешем опций: false и async: false. – Priyank

+1

Это безумие, чтобы попытаться сделать этот материал в jQuery, когда есть подходящие библиотеки mvvm, такие как нокаут и угловой – andrew

ответ

1

, кажется, функция getAccordionBody() не возвращает до HTML строка добавляется в DOM

Это правильно. Ваш путь returning the response (html3) from ajax является ошибочным - вы не можете return от done обработчика.

Вы можете исправить это, используя обещания. Каждая функция возвращает обещание так, что они легко прикованы, и 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

+0

Вы захотите [познакомиться с обещаниями] (https://github.com/kriskowal/q/wiki/General-Promise-Resources), конечно :-) – Bergi

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" 
}); 

затем итерацию по этой коллекции и собрать все данные для Accordian тела этих идентификаторов в любой глобальной переменной.

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; 
} 

Ваш Calling также будет изменена:

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

Вы Окончательный код wil l be:

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 
}); 
Смежные вопросы