Обновить данные KnockoutJS в DataTables - PullRequest
10 голосов
/ 11 января 2012

У меня есть следующая таблица

<table class="datatable zebra-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Issue</th>
            <th></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: Publications">
        <tr>
            <td><span data-bind="text: Name" /></td>
            <td><span data-bind="text: IssueNumber" /></td>
            <td><button type="button" class="btn" data-bind="click: $parent.DeletePublication">Delete</button></td>
        </tr>    
    </tbody>
</table>

Вот фрагмент модели представления:

function EditReaderViewModel() {
    var self = this;

    self.Publications = ko.observableArray([]);

    self.OnAddPublicationSaveButtonClicked = function () {
        //.. code omitted.    
        self.Publications.push(new Publication(publication.value, publication.label, publication.issueNumber));
    };
};

}

и объект Publication, связанный с таблицей:

function Publication(id, name, issueNumber) {
    var self = this;

    self.Id = id;
    self.Name = name;
    self.IssueNumber = issueNumber;
    self.LoadedFromDatabase = false;
}

Когда данные впервые загружаются в таблицу и инициализируются данными, например,

$(".datatable").dataTable({ // blahh });

Все отлично работает - данные загружаются в таблицу, работает сортировка и фильтрацияи т. д.

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

Может кто-нибудь подсказать мне, как перестроить таблицу данных, учитывая, что данные взяты из модели представления KnockoutJS?

Пожалуйстаобратите внимание, что я посмотрел на этот плагин привязки:

http://www.joshbuckley.co.uk/2011/07/knockout-js-datatable-bindings/

Проблема в том, что при использовании этого я получаю сообщения об ошибках, такие как:

Запрошен неизвестный параметр '0' из источника данных для строки 0.

РЕДАКТИРОВАТЬ:

Я просматриваю код и думаю, что вижу проблему.В jQuery.DataTables.js есть эта функция function _fnGetCellData( oSettings, iRow, iCol, sSpecific )

В этой функции есть эта строка:

if ( (sData=oCol.fnGetData( oData )) === undefined )

, которая, в свою очередь, вызывает:

function _fnGetObjectDataFn( mSource )

Теперь в function _fnGetObjectDataFn( mSource ) есть этот код, который называется:

else
{
    /* Array or flat object mapping */
    return function (data) {
         return data[mSource];
    };
} 

data - это не массив, это объект JSON, что означает, что приведенный выше код завершится ошибкой (return data[mSource];).

Я действительно не уверен, что здесь делать.

РЕДАКТИРОВАТЬ - ВАЖНО:

Как заметил один из комментаторов, и я только что подтвердил доступ к

http://www.joshbuckley.co.uk/2011/07/knockout-js-datatable-bindings

приведет к появлению троянского предупреждения.Поэтому, пожалуйста, имейте в виду, что этот URL теперь является большим НЕТ-НЕТ.

Ответы [ 3 ]

3 голосов
/ 30 июня 2015

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

При обновлении таблицы вы можете просто.clear(), а затем .destroy() стол.После этого просто переинициализируйте таблицу, используя уже известную .DataTable()

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

Вы просто должны добавитьлогический идентификатор, который вы установили в true при первой инициализации таблицы.И, конечно, вы должны привязать таблицу к переменной, чтобы иметь возможность использовать магию API DataTable для элемента DOM.

    if (managementLoadedDone){
            userTable.clear();
            userTable.destroy();
        }

Заполнить данные в вашей таблице

    userTable = $("#userTable").DataTable({responsive: true});
            usersLoaded = true;
1 голос
/ 12 января 2012

Вы упоминаете, что использовали подключаемый модуль с возможностью сбора данных, и получаете сообщение об ошибке «Запрошенный неизвестный параметр« 0 »из источника данных для строки 0».

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

Или, может быть, вы используете опцию «aoColumnDefs» при инициализации таблицы. Снова проверьте определение опции и убедитесь, что вы не пытались достичь неизвестного столбца:

Например, если у вас есть такое определение

"aoColumnDefs": [{
         "bSearchable": false,
         "bVisible": false,
         "aTargets": [0]
     }, {
         "bSortable": false,
         "bSearchable": false,
         "sWidth": "45px",
         "aTargets": [2]
     }]

и если у вас есть только 2 раздела thead, это даст вам эту ошибку. Потому что вы достигаете третьего столбца с aTargets: [2]

0 голосов
/ 05 июня 2012

У меня возникла похожая проблема, как вы описали здесь (и не собирался исследовать ссылку «привязки» после предупреждения Kaspersky, даже если она действительно безопасна).

Идетнемного о подходе, предложенном здесь KnockoutJs - как использовать таблицы данных с существующей связанной таблицей , я закончил тем, что выбрал маршрут, где при использовании нокаута в таблице я добавил оператор нокаута if, чтобы проверить, имел ли объект observableArrayхотя бы один ряд данных.

<!-- if Publications.length() > 0 -->
<table class="datatable zebra-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Issue</th>
        </tr>
    </thead>
    <tbody>
        <!-- ko foreach: Publications -->
        <tr>
            <td><span data-bind="text: Name" /></td>
            <td><span data-bind="text: IssueNumber" /></td>
        </tr>  <!-- /ko -->
    </tbody>
</table>
<!-- /ko -->

При загрузке модели представления я затем вызвал функцию dataTables внутри моей функции успеха .ajax.

Тогда другой частью работы было использование dataTables "bStateSave": true, чтобы любая сортировка, которую я делал до обновления, не была потеряна.

...