Нокаутом datbind JQuery Datatable добавить строку

Я работал над чертежными чертежами, в которых автор показывает способ пользовательского связывания данных с jquery. Однако у меня возникли некоторые трудности при добавлении новой строки. Вот скрипка, когда вы заполняете форму и нажимаете добавить, таблица данных становится пустой. http://jsfiddle.net/LkqTU/33382/

Я считаю, что данные не были успешно уничтожены и воссозданы.

здесь пользовательская привязка.

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

Вы можете запустить весь фрагмент ниже или использовать скрипку выше. Спасибо

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>

2 ответа

Решение

Проблема, которую я видел с вашим первым, заключается в том, что вы не обновили HTML-таблицу после того, как уничтожили DataTable.

Я обновил второй индекс здесь: 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>");

  });

Ну, не уверен, что это лучший способ, но я придумал это до сих пор.

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>

Другие вопросы по тегам