简体   繁体   中英

knockout databind jquery datatable to add a row

I was working through a book knockout blueprints where the author shows a way to custom bind a jquery datatable. however I am having a bit of difficulty adding a new row. here is the fiddle when you fill in the form and hit add the data table becomes empty. http://jsfiddle.net/LkqTU/33382/

I believe the datatable is not successfully destroyed and recreated.

here is the custom binding.

ko.bindingHandlers.dataTable = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var value = valueAccessor(),
      allBindings = ko.utils.unwrapObservable(allBindingsAccessor()),
      options = allBindings.dataTableOptions || {},
      $element = $(element);

    $element.dataTable(options);

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      $element.dataTable().fnDestroy();
    });
    value.subscribe(function(oldValue) {
      console.log('one');
     $element.dataTable().fnDestroy();
      $element.find("tbody tr").remove();

    }, null, "beforeChange");

    value.subscribe(function() {
      console.log('two');
      $element.dataTable(options);
    }, null);
  }
}

you can run the entire snippet below, or use the fiddle above. thanks

 ko.bindingHandlers.dataTable = { init: function(element, valueAccessor, allBindingsAccessor) { var value = valueAccessor(), allBindings = ko.utils.unwrapObservable(allBindingsAccessor()), options = allBindings.dataTableOptions || {}, $element = $(element); $element.dataTable(options); ko.utils.domNodeDisposal.addDisposeCallback(element, function() { $element.dataTable().fnDestroy(); }); value.subscribe(function(oldValue) { $element.dataTable().fnDestroy(); $element.find("tbody tr").remove(); }, null, "beforeChange"); value.subscribe(function() { $element.dataTable(options); }, null); } } function employee(id, firstName, lastName, phone, dept) { var self = this; this.id = ko.observable(id); this.firstName = ko.observable(firstName); this.lastName = ko.observable(lastName); this.phone = ko.observable(phone); this.dept = ko.observable(dept); } function model() { var self = this; this.employees = ko.observableArray([ new employee('1', 'Joe', 'Smith', '333-657-4366', 'IT') ]); this.id = ko.observable(''); this.firstName = ko.observable(''); this.lastName = ko.observable(''); this.phone = ko.observable(''); this.dept = ko.observable(''); this.add = function() { self.employees.push(new employee( this.id(), this.firstName(), this.lastName(), this.phone(), this.dept() )); // console.log(ko.toJSON(self.employees)) } } var mymodel = new model(); $(document).ready(function() { ko.applyBindings(mymodel); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script> <link href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <table data-bind="dataTable: employees"> <thead> <tr> <th>Id</th> <th>First</th> <th>Last</th> <th>Phone</th> <th>Dept</th> </tr> </thead> <tbody data-bind="foreach: employees"> <tr> <td data-bind="text: id"></td> <td data-bind="text: firstName"></td> <td data-bind="text: lastName"></td> <td data-bind="text: phone"></td> <td data-bind="text: dept"></td> </tr> </tbody> </table> <p style="padding-top: 20px;"> Id: <input data-bind="textInput: id" /> </p> <p> First: <input data-bind="textInput: firstName" /> </p> <p> Last: <input data-bind="textInput: lastName" /> </p> <p> phone: <input data-bind="textInput: phone" /> </p> <p> dept: <input data-bind="textInput: dept" /> </p> <p> <input type="button" value="add employee" data-bind="click: add" /> </p>

The problem I saw with your first one is that you did not update the html table after you destroyed the DataTable.

I updated the second subscript here: http://jsfiddle.net/bindrid/LkqTU/33392/

value.subscribe(function(rowData) {
  var $tb = $element.find("tbody");
  $.each(rowData, function(idx, item) {
    $tb.append("<tr><td>" + item.id() + "</td><td>" + item.firstName() + "</td><td>" + item.lastName() + "</td><td>" + item.phone() + "</td><td>" + item.dept() + "</td></tr>");

  });

well not sure if this is the best way but I came up with this so far.

 ko.bindingHandlers.dataTable = { init: function(element, valueAccessor, allBindingsAccessor) { var value = valueAccessor(), rows = ko.toJS(value); allBindings = ko.utils.unwrapObservable(allBindingsAccessor()), options = allBindings.dataTableOptions || {}, $element = $(element); $element.dataTable(options); ko.utils.domNodeDisposal.addDisposeCallback(element, function() { $element.dataTable().fnDestroy(); }); }, update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { var value = valueAccessor(), rows = ko.toJS(value); console.log(rows); $(element).find("tbody tr").remove(); var table = $(element).DataTable(); table.clear().draw(); $.each(rows, function(index, row) { var myArray = []; $.each(row, function(key, value) { myArray.push(value) }); table.row.add(myArray).draw().node() }); } } function employee(id, firstName, lastName, phone, dept) { var self = this; this.id = ko.observable(id); this.firstName = ko.observable(firstName); this.lastName = ko.observable(lastName); this.phone = ko.observable(phone); this.dept = ko.observable(dept); } function model() { var self = this; this.employees = ko.observableArray('') this.id = ko.observable(''); this.firstName = ko.observable(''); this.lastName = ko.observable(''); this.phone = ko.observable(''); this.dept = ko.observable(''); this.add = function() { self.employees.push(new employee( this.id(), this.firstName(), this.lastName(), this.phone(), this.dept() )); // console.log(ko.toJSON(self.employees)) } } var mymodel = new model(); $(document).ready(function() { ko.applyBindings(mymodel); mymodel.employees.push(new employee('1', 'Joe', 'Smith', '333-657-4366', 'IT')) });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script> <link href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <table data-bind="dataTable: employees"> <thead> <tr> <th>Id</th> <th>First</th> <th>Last</th> <th>Phone</th> <th>Dept</th> </tr> </thead> <tbody> </tbody> </table> <p style="padding-top: 20px;"> Id: <input data-bind="textInput: id" /> </p> <p> First: <input data-bind="textInput: firstName" /> </p> <p> Last: <input data-bind="textInput: lastName" /> </p> <p> phone: <input data-bind="textInput: phone" /> </p> <p> dept: <input data-bind="textInput: dept" /> </p> <p> <input type="button" value="add employee" data-bind="click: add" /> </p>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM