使用Knockout BindingHandler公开JQuery.Datatables选择?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Knockout BindingHandler公开JQuery.Datatables选择?相关的知识,希望对你有一定的参考价值。

我已经设置了custom KO bindingHandler来帮助更新DataTable。

关于如何获取数据的JQuery.DataTable.Select的documentation需要一个句柄。

var table = $('#myTable').DataTable();

table.rows( { selected: true } ).data();

但是,我的ko.bindingHandler将DataTable的设置移动到我的cshtml文件中,因此我没有$('#myTable').DataTable()的句柄。

如何使我的viewModel可以使用DataTable函数?我曾经以为我可以使用JQuery将$('#myTable')作为dataTable进行投射,但我没有运气。

.cshtml:

<table id="myTable">
   <thead>
     <tr>
       <th>Title</th>
   </thead>
   <tbody data-bind="dataTablesForEach: {data: trainingSearchResults, dataTableOptions: {
                select: {items: 'row', style: 'os'},
                searching: false,
                info: false,
                paging: false
              }">
       <tr>
         <td data-bind="text: title"></td>
       </tr>
  </tbody>
</table>

自定义绑定:

import * as ko from "knockout"
import * as $ from "jquery";

export class KnockoutExtensions {
    // Constructor
    constructor() {
        ko.bindingHandlers.dataTablesForEach = {
            page: 0,
            init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                var options = ko.unwrap(valueAccessor());
                ko.unwrap(options.data);
                if (options.dataTableOptions.paging) {
                    valueAccessor().data.subscribe(function (changes) {
                        var table = $(element).closest('table').DataTable();
                        ko.bindingHandlers.dataTablesForEach.page = table.page();
                        table.destroy();
                    }, null, 'arrayChange');
                }
                var nodes = Array.prototype.slice.call(element.childNodes, 0);
                ko.utils.arrayForEach(nodes, function (node: Node) {
                    if (node && node.nodeType !== 1) {
                        node.parentNode.removeChild(node);
                    }
                });
                return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
            },
            update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
                var options = ko.unwrap(valueAccessor()),
                    key = 'DataTablesForEach_Initialized';
                ko.unwrap(options.data);
                var table;
                if (!options.dataTableOptions.paging) {
                    table = $(element).closest('table').DataTable();
                    table.destroy();
                }
                ko.bindingHandlers.foreach.update(element, valueAccessor, allBindings, viewModel, bindingContext);
                table = $(element).closest('table').DataTable(options.dataTableOptions);
                if (options.dataTableOptions.paging) {
                    if (table.page.info().pages - ko.bindingHandlers.dataTablesForEach.page == 0)
                        table.page(--ko.bindingHandlers.dataTablesForEach.page).draw(false);
                    else
                        table.page(ko.bindingHandlers.dataTablesForEach.page).draw(false);
                }
                if (!ko.utils.domData.get(element, key) && (options.data || options.length))
                    ko.utils.domData.set(element, key, true);
                return { controlsDescendantBindings: true };
            }
        }; 
    }
}
答案

尝试从我的viewModel再次调用初始化时:

var table = $("#trainingSearchResultsTable").DataTable({
    select: { items: 'row', style: 'os' },
    searching: false,
    info: false,
    paging: false
});

给我一个错误Warning: Cannot reinitialise

它引导我到answer

当已初始化所选节点的DataTable实例时,通过将选项传递给DataTables构造函数对象来触发此错误。

对象实例检索

尝试获取DataTable的引用以使用API​​时,通常会发生此错误。例如,您可能有一个函数,它总是尝试通过在创建时传入选项来创建DataTable实例。然后进行修改,在已经初始化的表上调用此函数,然后出现此错误。

在这种情况下,您将需要使用$ .fn.dataTable.isDataTable()静态方法。这可以用于检查表是否已经是DataTable:

if ( $.fn.dataTable.isDataTable( '#example' ) ) {
    table = $('#example').DataTable();
}
else {
    table = $('#example').DataTable( {
        paging: false
    } );
}

以上是关于使用Knockout BindingHandler公开JQuery.Datatables选择?的主要内容,如果未能解决你的问题,请参考以下文章

淘汰赛 - 将值写入 ko.computed

利用输入掩码使用 Knockout 自定义绑定禁用 Knockout 验证

knockout.js入门

我是不是有理由使用 Knockout MVC 而不是 Knockout JS?

使用 Knockout 订阅的循环依赖

knockout.js 虚拟模板绑定