使用knockout自定义绑定时,jquery datatable不删除行

时间:2017-07-24 10:42:34

标签: javascript knockout.js datatables

我正在尝试为knockout jquery数据表创建自定义绑定。 (我正在处理有人发布的现有SO问题)除了添加新行之外,一切似乎都运行良好。数据表还添加了已存在的行。我的意思是数据表上的.draw()函数没有触发。这是小提琴。

http://jsfiddle.net/LkqTU/35814/

如果您填写表单并单击添加,您将注意到原始行重复。

这是我的约束力。

ko.bindingHandlers.dataTable = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    var value = valueAccessor(),
      rows =  ko.toJS(value);
      allBindings = ko.utils.unwrapObservable(allBindingsAccessor()),
      $element = $(element);

   var table =  $element.DataTable( {
         data: rows,
          columns: [
            { data: "id" },
            { data: "firstName" },
            { data: "lastName" },
            { data: "phone" },
            {
               data: "ssn",
                "render": function ( data, type, full, meta ) {
                return '<a href="/Medlem/'+data+'">' + data + '<a>';
             }
           }
        ]
    } );
    alert('added');

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
      $element.dataTable().fnDestroy();
    });

    value.subscribe(function(newValue) {
     rows = ko.toJS(newValue)
     console.log(rows);
       $element.find("tbody tr").remove();
       table.rows().remove().draw();
     $.each(rows, function( index, row ) {
            table.row.add(row).draw()
        });

    }, null);
  }
}

我刚注意到我是否将添加设置超时添加到添加行的部分。一切正常。很奇怪。

setTimeout(function(){    $.each(rows, function( index, row ) {
            table.row.add(row).draw()
        });
     }, 0);

这是更新的小提琴。 http://jsfiddle.net/LkqTU/35820/

1 个答案:

答案 0 :(得分:3)

它具体与draw()电话的时间有关。这是因为你的表中有一个Knockout绑定,所以你有jQuery和Knockout试图管理这个DOM,并且它们互相踩踏。

答案:您根本不需要桌面主体; DataTables将为您提供。

我重新组织了一些代码,使用bindingHandler的update部分进行数据更新。

ko.bindingHandlers.dataTable = {
  init(element, valueAccessor, allBindingsAccessor) {
      const $element = $(element);

      $element.DataTable({
        columns: [{
          data: "id"
        }, {
          data: "firstName"
        }, {
          data: "lastName"
        }, {
          data: "phone"
        }, {
          data: "ssn",
          "render": function(data, type, full, meta) {
            return '<a href="/Medlem/' + data + '">' + data + '<a>';
          }
        }]
      });

      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
        $element.dataTable().fnDestroy();
      });
    },
    update(element, valueAccessor, allBindingsAccessor) {
      const rows = ko.toJS(valueAccessor());
      const table = $(element).DataTable();

      table.clear().rows.add(rows).draw();
    }
}



function employee(id, firstName, lastName, phone, ssn) {
  var self = this;
  this.id = ko.observable(id);
  this.firstName = ko.observable(firstName);
  this.lastName = ko.observable(lastName);
  this.phone = ko.observable(phone);
  this.ssn = ko.observable(ssn);
}

function model() {
  var self = this;
  this.employees = ko.observableArray([
    new employee('1', 'Joe', 'Smith', '333-657-4366', '111-11-1111')
  ]);
  this.id = ko.observable('');
  this.firstName = ko.observable('');
  this.lastName = ko.observable('');
  this.phone = ko.observable('');
  this.ssn = ko.observable('');
  this.add = function() {
    self.employees.push(new employee(
      this.id(), this.firstName(), this.lastName(), this.phone(), this.ssn()
    ));
  }
}

var mymodel = new model();

$(document).ready(function() {
  ko.applyBindings(mymodel);
});
<link href="//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>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<table data-bind="dataTable: employees">
  <thead>
    <tr>
      <th>Id</th>
      <th>First</th>
      <th>Last</th>
      <th>Phone</th>
      <th>ssn</th>
    </tr>
  </thead>
</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>
  ssn:
  <input data-bind="textInput: ssn" />
</p>
<p>
  <input type="button" value="add employee" data-bind="click: add" />
</p>