javascript - KnockoutJs - how to use datatables with existing bound table - Stack Overflow

I have a simple HTML table which is bound using knockoutJS.However, I've added a custom binding

I have a simple HTML table which is bound using knockoutJS. However, I've added a custom binding which applies the jquery datatable plugin on the table.

When I click the headers, the table disappears. Any idea how I can get it working with knockoutJS?

I have a simple HTML table which is bound using knockoutJS. However, I've added a custom binding which applies the jquery datatable plugin on the table.

When I click the headers, the table disappears. Any idea how I can get it working with knockoutJS?

Share Improve this question asked Mar 23, 2012 at 9:27 jaffajaffa 27.4k51 gold badges180 silver badges293 bronze badges 2
  • 1 I think you need to provide some code if you expect help on this. – Mikael Östberg Commented Mar 23, 2012 at 9:30
  • Its ok I figured it ok. Most examples of using dataTables with knockoutJs are not progressively enhancing existing tables. They work by using KnockoutJs to attach the dataTables data source to an ajax end-point. See my solution below. – jaffa Commented Mar 23, 2012 at 11:08
Add a ment  | 

2 Answers 2

Reset to default 3

Its actually unnecessary to use knockoutJs to carry out the binding of the dataTable. As knockoutJs already binds the HTML table to the model, just use the following:

$(function() {
        var dtOptions = {
                "bPaginate": false,
                "bLengthChange": false,
                "bFilter": false,
                "bInfo": false,
                bJQueryUI: true              
        }

        var dt = $("#leadsTable").dataTable(dtOptions);

        $("#searchButton").click(function() {
           //... set url with search terms...

           $.get(url, function (data) {
                // destroy existing table
                dt.fnDestroy();

                ko.mapping.fromJS(data, vm.model);

                // re-created AFTER ko mapping
                dt.dataTable(dtOptions);                    
           });
       })
});

var serialisedModel = @Html.Raw(new JavaScriptSerializer().Serialize(Model));

var vm = {      
    data: ko.toJSON(serialisedModel),
}

ko.applyBindings(vm);

The crucial part is to destroy the existing dataTable before the mapping, and re-create after mapping. I had to keep a reference to the initial dataTable for later destroying...

This is the way to do it... I have made a jsfiddle showing this:

Here is a knockout custom binding solution for jQuery datatables.

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) {
        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 };
}}; 

JSFiddle w/ jqueryUI

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742310158a4419728.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信