Вот JS-код:
function ProductViewModel() {
// Init.
var self = this;
self.products = ko.observableArray();
self.singleProduct = ko.observable();
var mappedProducts;
// Initialize table here.
$.getJSON("/admin/test", function(allData) {
mappedProducts = $.map(allData, function(item) { return new Product(item);});
self.products(mappedProducts);
self.oTable = $('#products-table').dataTable( {
"aoColumns": [
{ "bSortable": false, "mDataProp": null, sDefaultContent: '' },
{"mData": "name"},
{"mData": "dealer"},
{"mData": "cost"},
{"mData": "price"},
{ "bSortable": false, sDefaultContent: '' }
],
});
});
// Here i'm using the basic switch pattern, as from KO tutorials.
// This is intended for showing a single product form.
self.edit = function(product) {
self.singleProduct(product);
}
// This is intended to hide form and show list back.
self.list = function() {
self.singleProduct(null);
}
// This is the form save handler, actually does nothing
// but switch the view back on list.
self.doEdit = function(product) {
self.list();
}
}
// My model.
function Product(item) {
this.name = ko.observable(item.name);
this.dealer = ko.observable(item.dealer);
this.cost = ko.observable(item.cost);
this.price = ko.observable(item.price);
this.picture = ko.observable();
}
Вот моя разметка:
<table id="products-table" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Pic</th>
<th>Name</th>
<th>Dealer</th>
<th>Cost</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: $parent.products">
<tr>
<td><span data-bind='ifnot: picture'>-</span></td>
<td><a data-bind="text: name"></a></td>
<td><span data-bind='text: dealer'></span></td>
<td><span data-bind='text: cost'></span></td>
<td><span data-bind='text: price'></span></td>
<td>
<button data-bind='click: $root.edit'><i class='icon-pencil'></i>
</button>
</td>
</tr>
</tbody>
</table>
Когда я нажимаю кнопку редактирования, запуская обработчик $root.edit, форма отображается из-за
<div data-bind='with: singleProduct'>
привязку я сделал. Внутри этой привязки у меня есть форма с
<input data-bind="value: name" type="text" id="" placeholder="Name"
> class="col-xs-10 col-sm-5">
поле.
Проблема: когда я редактирую значение в поле ввода, относительная строка в таблице данных не обновляется. Я попробовал базовую таблицу без плагина datatables, и она работает, а это означает, что если я изменю значение, строка в таблице будет правильно обновлена.
Что здесь не так?
== ИЗМЕНИТЬ ==
Я обнаружил, что перемещение точки привязки к таблице TD решило проблему, хотя до сих пор не могу понять, почему.
<tr>
<td data-bind="text: name"></td>
<!-- More columns... -->
</tr>
Приведенный выше код теперь работает правильно. Почему ?
== РЕДАКТИРОВАТЬ2 ==
Теперь, когда я исправил первую проблему, приходит вторая. Я реализовал свой метод «сохранить новый» так
self.doAdd = function(product) {
$.ajax("/product/", {
data: ko.toJSON({ product: product }),
type: "post", contentType: "application/json",
success: function(result) { alert('ehh'); }
}).then(function(){
self.products.push(product); // <--- Look at this!
self.list();
});
}
self.products.push(product); в обработчике успеха правильно обновляет наблюдаемые продукты. Затем в мою таблицу автоматически добавляется новая строка, и это хорошая новость.
Плохая новость заключается в том, что элементы управления таблицами данных, такие как поле поиска или интерактивные стрелки сортировки, исчезают, как только я помещаю новый продукт в массив. Почему так!?