2017-02-22 5 views
1

Я пытаюсь заполнить DataTable информацией, собранной из API.Как добавить данные из API в HTML DataTable?

Я сделал «скрипку» здесь, чтобы сделать его проще, чтобы помочь и понять, что я имею в виду: http://live.datatables.net/jujofoye/3/edit

Я начинаю из HTML-таблицы, содержащей только идентификаторы. Затем я использую этот идентификатор в rowCallback для вызова API и писать сгружен значение в таблице с JQuery $('td:eq(1)', nRow).html(json.Title);

function customFnRowCallback(nRow, aData, iDisplayIndex) { 
    var imdbID = aData[0]; 

    fetch("http://www.omdbapi.com/?i="+imdbID+"&plot=short&r=json&tomatoes=true") 
    .then(function(response) { 
    return response.json(); 
    }) 
    .then(function(json) { 
    $('td:eq(1)', nRow).html(json.Title); 
    }) 
    .catch(function(error) { 
    console.log('There has been a problem with your fetch operation: ' + error.message); 
    }); 
} 

Однако проблема здесь заключается в том, что вы не можете сортировать по второй колонке. Несмотря на то, что данные можно увидеть отлично. Я уверен, что DataTable действительно не знает, что есть новые данные, и вы в конечном итоге сортируете пустые значения вместо добавленных значений.

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

Есть ли способ действительно добавить данные в DataTable? Это не косметически.

(Примечание. Все ответы можно найти около заселения полного DataTable с просьбой AJAX Я только добавить данные к уже населенной DataTable)

+0

Любая конкретная причина, почему вы не получите данные первого затем построить таблицу как предложил Питер Чон или использовать Аякса, который является частью DataTable апи? – Bindrid

+0

@Bindrid Да, rowCallback работает только для видимых данных. Так что даже если у вас миллион записей, вызовы api ограничены, так как вы можете видеть здесь, api работает только 10x: http://live.datatables.net/jujofoye/11/edit –

+0

@Bindrid еще одна причина в том, что я не знаете, когда ответы api будут возвращены, прежде чем я смогу построить данные, это может занять много непредсказуемого времени. –

ответ

1

Я принял другой подход. Я использовал DataTable ajax с помощью/done, чтобы он не обновлял таблицу до тех пор, пока все получатели не будут обработаны.

Я установил сортировку, чтобы список выходил в алфавитном порядке, даже те, которые не являются порядком списка. Я также получил уникальный набор значений из imdb.

http://jsbin.com/yojoka/edit?html,js,output

<script type="text/javascript"> 
    // Sample return set from 
    var sampleReturn = { "Title": "Seven Samurai", "Year": "1954", "Rated": "UNRATED", "Released": "19 Nov 1956", "Runtime": "207 min", "Genre": "Adventure, Drama", "Director": "Akira Kurosawa", "Writer": "Akira Kurosawa (screenplay), Shinobu Hashimoto (screenplay), Hideo Oguni (screenplay)", "Actors": "Toshirô Mifune, Takashi Shimura, Keiko Tsushima, Yukiko Shimazaki", "Plot": "A poor village under attack by bandits recruits seven unemployed samurai to help them defend themselves.", "Language": "Japanese", "Country": "Japan", "Awards": "Nominated for 2 Oscars. Another 5 wins & 6 nominations.", "Poster": "https://images-na.ssl-images-amazon.com/images/M/[email protected]_V1_SX300.jpg", "Metascore": "98", "imdbRating": "8.7", "imdbVotes": "238,165", "imdbID": "tt0047478", "Type": "movie", "Response": "True" }; 
    var deferreds = []; 
    var newData = []; 
    $(function ($) { 
     var dt = $("#example").DataTable({ 
      columnDefs:[{targets:[0, -1], width:"150px"}], 
      columns: [ 
       { data: "imdbID" }, 
       { data: "Title" }, 
       { "data": "Year" } 
      ], 
      deferLoading: 0, 
      deferRendering: true, 
      "order": [[ 1, "asc" ]], 
      ajax: function (data, cb, setting) { 
       // get the list of ids created by DataTables from the embedded html 
       var curData = $("#example").DataTable().rows().data(); 
       // if you don't clear, you will end up with double entries 
       $("#example").DataTable().clear(); 
       $.each(curData, function (i, item) { 
        var sr = { i: item.imdbID, plot:"short", r:"json", "tomatoes":true}; 
        deferreds.push(
        $.get("http://www.omdbapi.com/", sr) 
        .then(function (response) { 
         // push the response into the global array 
         newData[newData.length] = response; 
        }) 
       ); 
       }); 

       // now make all of the calls. When done, use the callback to return the data and populate the table 
       $.when.apply(null, deferreds) 
        .done(function() { 
         cb({ data: newData }) 
       }); 
      } 
     }); 
    }); 
</script> 
+0

Это работает. Благодаря! (Я потерял ленивую загрузку, но мне нужно что-то найти для этого.) –

+0

Если вы хотите, чтобы сортировать по столбцам по всем столбцам, вы все равно откажетесь от ленивой загрузки. Если вы готовы отказаться от поиска и сортировки, вы можете одновременно ввести страницу данных. К сожалению, ваши возможности ограничены, потому что вы работаете с интерфейсом omdbapi, и их варианты довольно ограничены. – Bindrid

0

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

$('#example').find('tbody tr').each(customFnRowCallback); 

function customFnRowCallback() 
{ 
    var $this = $(this); 
    var imdbID = $this.find('td:eq(0)').text(); 

    fetch("http://www.omdbapi.com/?i="+imdbID+"&plot=short&r=json&tomatoes=true") 
    .then(function(response) { 
    return response.json(); 
    }) 
    .then(function(json) { 
    $this.find('td:eq(1)').text(json.Title); 
    }) 
    .then(function() { 
    $('#example').DataTable(); 
    }) 
    .catch(function(error) { 
    console.log('There has been a problem with your fetch operation: ' + error.message); 
    }); 
} 
+0

Это работает, но имеет 2 проблемы: 1) если у меня есть миллион строк, это вызовет миллион вызовов api. Вы знаете, как это сделать только для видимых строк? 2) Как я узнаю, когда все вызовы api закончены, чтобы запустить datatable? –

+0

Ну, на основе вашего исходного кода вы делаете звонок для каждого идентификатора. Поэтому я не знаю, что сказать об этом. Обычно мы вызываем вызов, а затем создаем всю таблицу на основе возвращаемого объекта. Проблема с вашей ситуацией заключается в том, что вы динамически добавляете данные, поэтому .DataTable() не знает, что сортировать. –

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