2017-02-13 2 views
2

Я делаю несколько вызовов Ajax для получения страховых котировок от разных поставщиков с целью агрегирования и сортировки результатов. Мой упрощен код выглядит следующим образом:Использование jQuery для сортировки и отображения данных Ajax на лету

for (var i = 0; i < providerList.length; i++) { 
 
\t $.ajax({ 
 
\t url : "quote-request/"+ providerList[i] +".php", 
 
\t type: "GET", 
 
\t data : formData, 
 
\t dataType:"json", 
 
\t success: function(results) { 
 
\t  $.each(results, function(index, value) { \t \t \t \t \t 
 
\t  $("#results").append("<div>" + value["provider-name"] + value["policy-name"] + value["grand-total"] + "</div>"); 
 
\t  }) 
 
\t } 
 
     }); 
 
}

Который производит:

<div id="results"> 
    <div>ProviderA Policy1 12.34</div> 
    <div>ProviderA Policy2 9.50</div> 
    <div>ProviderB Policy1 22.76</div> 
</div> 

Однако я хотел бы результаты, которые можно заказать в порядке возрастания от внучатая общей как каждый Ajax завершает так, чтобы каждый новый результат автоматически вставлялся в нужное место:

<div id="results"> 
    <div>ProviderA Policy2 9.50</div> 
    <div>ProviderA Policy1 12.34</div> 
    <div>ProviderB Policy1 22.76</div> 
</div> 

Единственный способ, которым я могу это сделать, - сохранить каждый результат в массиве после каждого вызова Ajax, затем отсортировать массив и вывести результаты, но кажется немного лишним, чтобы продолжать строить и выводить один и тот же массив каждый раз, когда извлекается новая цитата. Есть ли лучший способ сделать это?

Чтобы уточнить, окончательный сценарий составит около 10 вызовов Ajax и загрузит около 40 результатов, поэтому мы не говорим о огромных наборах данных здесь. Также возможно, что один или несколько котировок будут иметь одинаковые итоговые, и в этом случае не важно, что на первом месте. Каждая цитата также будет иметь уникальный идентификатор, policy-id, если это полезно здесь.

+0

Я не вижу никаких других способов, кроме повторного строительства каждый раз. Вы можете разобрать таблицу для каждой новой записи и попытаться выяснить, куда она идет, но это потребует гораздо большего процесса, чем просто перестроить приложение. Вы также можете просто сделать один звонок, который берет все данные, сортирует их и строит таблицу только один раз. – Nicolas

ответ

2

Да, это намного быстрее, если вы можете вставить элемент DOM прямо в порядок. И это можно сделать. Вы можете по существу использовать DOM в качестве псевдо-массива и использовать атрибут data в DOM для отслеживания ваших значений. Вы можете написать короткий скрипт для поиска вашего «псевдо-массива» в DOM и найти соответствующий индекс для вставки новых элементов.

Вот короткая функция, которая должна работать на вас. Я также издевался над ней в скрипкой с некоторыми случайными данными по таймеру, чтобы показать, как это будет работать:

function insertInline(providerName, policyName, grandTotal) { 
    var curDomElement; 
    var prevDomElement; 
    var insertBefore; 
    $('#results div').each(function(index) { 
    prevDomElement = curDomElement; 
    curDomElement = $(this); 
    if (parseInt(curDomElement.data('grandtotal')) > grandTotal) { 
     insertBefore = curDomElement; 
     return false; 
    } 
    }); 
    if (insertBefore) { 
    $("<div data-grandTotal='" + grandTotal + "'>" + providerName + policyName + grandTotal + "</div>").insertBefore(insertBefore); 
    } else { 
    $("#results").append("<div data-grandTotal='" + grandTotal + "'>" + providerName + policyName + grandTotal + "</div>"); 
    } 
} 

А в вашем примере вы будете использовать его в основном как это:

for (var i = 0; i < providerList.length; i++) { 
    $.ajax({ 
     url : "quote-request/"+ providerList[i] +".php", 
     type: "GET", 
     data : formData, 
     dataType:"json", 
     success: function(results) { 
      $.each(results, function(index, value) { 
      insertInline(value["provider-name"], value["policy-name"], parseInt(value["grand-total"])); 
      }) 
     } 
    }); 
} 

работа образца: https://jsfiddle.net/mspinks/vnofjobu/

+0

Спасибо, Мэтт, это сработало отлично (хотя вы пропустили закрывающий кронштейн, где вы вызвали функцию во время цикла ajax). Кроме того, это хорошее решение, спасибо. – Calico

+0

Без проблем @Calico. Я рад, что это сработает для вас. Спасибо, что указали на отсутствующий кронштейн. Я отредактировал ответ, чтобы исправить его. –

0

Я думал о чем-то, что может сработать. Вы можете назначить общее количество (элемент, который вы сортируете), в атрибут в каждом div. Затем вы можете использовать jQuery для размещения элементов в div results на основе итогового итога.

Итак, когда вы получите первый элемент, вы просто добавите это в div results, но вы также дадите атрибуту div атрибут (я назвал его значением, вы можете называть его так, как хотите):

<div value='what-grand-total-is'></div> 

Тогда для всех остальных элементов, вы получите общий итог текущего элемента, сбегать существующий список результатов, и для каждого элемента, проверьте великий итог и если вы столкнетесь с ребенком, что имеет большую сумму, чем текущий элемент, поместите текущий элемент до этого ребенка.

for (var i = 0; i < providerList.length; i++) { 
    $.ajax({ 
     url : "quote-request/"+ providerList[i] +".php", 
     type: "GET", 
     data : formData, 
     dataType:"json", 
     success: function(results) { 
      $.each(results, function(index, value) { 

      // no children, so append first time 
      if($('#results').children.length == 0) {  

      // assign attribute value (or whatever name you want) to div 
      $("#results").append("<div value=" + value["grand-total"] +">" + value["provider-name"] + value["policy-name"] + value["grand-total"] + "</div>"); 

      // if there are items in #results 
      } else {  
      // assuming this is returned as type integer 
      var currentTotal = value["grand-total"]; 

      // for every child 
      $('#results').children('div').each(function() { 

       // get grand-total from attribute of current div 
       var childTotal = this.attr('value');  

       // convert current div's grand total value from string to float, so we can compare values 
       childTotal = parseFloat(childTotal);  

       // if the div we're currently at is greater than or equal to the current result total 
       if (currentTotal <= childTotal) {   
       // place the current result in front of the div we're at 
       $(this).before("<div value=" + value["grand-total"] +">" + value["provider-name"] + value["policy-name"] + value["grand-total"] + "</div>");      // place the current result total before the current child 
       } 
      }); 
      } 
     }) 
     } 
    }); 
} 

Этот подход должен работать для любого числа AJAX запросов, а также с таким образом, вы не должны следить за массив и он может добавить данные, как она идет.

0

Вы можете отметить каждый результат с data- attrubute пролетом HAVING html5 в:

http://html5doctor.com/html5-custom-data-attributes/

Таким образом, вы можете создать дивы вроде этого:

<div id="results"> 
    <div data-provider="ProviderA" data-policy="Policy1" data-grandtotal="9.50">ProviderA Policy1 12.34</div> 
    <div data-provider="ProviderA" data-policy="Policy2" data-grandtotal="9.50">ProviderA Policy2 9.50</div> 
    <div data-provider="ProviderA" data-policy="Policy2" data-grandtotal="22.76" >ProviderB Policy1 22.76</div> 
</div> 

После этого вы можете извлечь данные, как, что используя эту функцию:

var getDataFromDom=function(){ 
    var resultData=[]; 

    $("#results").children().each(function(idx,val){ 
    var result={ 
     'provider':$(val).data('provider'), 
     'policy':$(val).data('policy'), 
     'grand-total':parseFloat($(val).data('grandtotal')) 
    } 

    resultData.push(result); 
    }); 

    return resultData; 
} 

После этого вы можете использовать функцию сортировки в JavaScript, чтобы отсортировать его: http://www.w3schools.com/jsref/jsref_sort.asp

Тогда только думаю, что вам нужно, чтобы при нажатии на соответствующую кнопку сортировки: * Получить data- приписано от дел. * Храните их в массиве. * Сортируйте их с помощью функции javascript sort() с правильным обратным вызовом. * Удалите все элементы из div. * Итерируйте массив и добавьте его внутри div.

И все будет в порядке.

PS Я использовал последнюю версию JQuery (3.1.1), если вы используете более раннюю версию, заменив функцию data() на attr(), например, напр. $(val).data('provider') будет $(val).attr('data-provider').

Смежные вопросы