使用 Knockout BindingHandler 公开 JQuery.Datatables Select?
Using Knockout BindingHandler to expose JQuery.Datatables Select?
我已经设置了一个 custom KO bindingHandler 来帮助更新数据表。
documentation对于JQuery.DataTable.Select如何获取数据需要句柄
var table = $('#myTable').DataTable();
table.rows( { selected: true } ).data();
但是,我的 ko.bindingHandler 将 DataTable 的设置移到了我的 cshtml 文件中,因此我没有 $('#myTable').DataTable()
.
的句柄
如何使 DataTable 函数可用于我的 viewModel?
我原以为我可以使用 JQuery 将 $('#myTable') 转换为数据表,但我没有这样的运气。
.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:
This error is triggered by passing in options to a DataTables
constructor object when the DataTable instance for the selected node
has already been initialised.
Object instance retrieval
This error can often occur when trying to obtain a reference to the
DataTable for working with the API. For example, you might have a
function which will always try to create a DataTable instance by
passing in options when created. Then you make a modification which
calls this function on a table which has already been initialised and
you get this error.
In such a case, you will want to use the $.fn.dataTable.isDataTable()
static method. This can be used to check if a table is a DataTable or
not already:
if ( $.fn.dataTable.isDataTable( '#example' ) ) {
table = $('#example').DataTable();
}
else {
table = $('#example').DataTable( {
paging: false
} );
}
我已经设置了一个 custom KO bindingHandler 来帮助更新数据表。
documentation对于JQuery.DataTable.Select如何获取数据需要句柄
var table = $('#myTable').DataTable(); table.rows( { selected: true } ).data();
但是,我的 ko.bindingHandler 将 DataTable 的设置移到了我的 cshtml 文件中,因此我没有 $('#myTable').DataTable()
.
如何使 DataTable 函数可用于我的 viewModel? 我原以为我可以使用 JQuery 将 $('#myTable') 转换为数据表,但我没有这样的运气。
.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:
This error is triggered by passing in options to a DataTables constructor object when the DataTable instance for the selected node has already been initialised.
Object instance retrieval
This error can often occur when trying to obtain a reference to the DataTable for working with the API. For example, you might have a function which will always try to create a DataTable instance by passing in options when created. Then you make a modification which calls this function on a table which has already been initialised and you get this error.
In such a case, you will want to use the $.fn.dataTable.isDataTable() static method. This can be used to check if a table is a DataTable or not already:
if ( $.fn.dataTable.isDataTable( '#example' ) ) { table = $('#example').DataTable(); } else { table = $('#example').DataTable( { paging: false } ); }