我有一个使用knockout.js生成的项目表,然后我使用此代码使每行上的某些项目可编辑:
function setupDeliveryItemsTable() {
//console.log('doing setupDeliveryItemsTable');
$('#deliveryItemsTable').tablesorter({ widgets: ['zebra'], headers: { 4: { sorter: false } } });
// Select field edit in places
var fields = $("#deliveryItemsTable div[id^='edit_select-delivery_items-']").map(function() { return this.id; }).get();
var options = {
type: 'select',
loadurl: SITE_URL + '/ajax.php?action=getDeliveryDriversJSON'
};
$.each(fields, function() {
// Determine our settings
var id = this;
var table = id.replace(/edit_select-([a-zA-Z_]+?)-([0-9]+?)_(.*)/, '$1');
var dbID = id.replace(/edit_select-([a-zA-Z_]+?)-([0-9]+?)_(.*)/, '$2');
var name = id.replace(/edit_select-([a-zA-Z_]+?)-([0-9]+?)_(.*)/, '$3');
var default_options = {
id : 'cssID',
cancel : '<button class="btn btn-default btn-sm editable-cancel" type="button"><i class="glyphicon glyphicon-remove"></i></button>',
submit : '<button class="btn btn-primary btn-sm editable-submit" type="submit"><i class="glyphicon glyphicon-ok"></i></button>',
indicator : indicatorImage,
tooltip : 'Click to edit...',
style : 'display: inline;',
width : 'none'
};
options = $.extend({}, default_options, options);
if ( options.loadurl ) { options.loadurl += '&id=' + dbID; }
$('#' + id).addClass('editableItemHolder').editable(
SITE_URL + '/ajax.php?action=updateDeliveryDriverByID&id=' + dbID,
options
);
});
var fields = $("#deliveryItemsTable div[id^='edit-delivery_items-']").map(function() { return this.id; }).get();
options = {
type: 'textarea',
};
addEditable( fields, options );
}
基本上,此代码对每行上的几个项目做出反应,如下所示:
<td><div id="edit-delivery_items-62_location">St 156 # 17 ( Phsa Depo )</div></td>
<td><div id="edit-delivery_items-62_notes">Not Pick up 20/05</div></td>
<td><div id="edit_select-delivery_items-62_delivered_by">Click to edit</div></td>
每次替换表的数据时,都会重新运行此代码。因此,如果执行搜索,则会更改表数据并重新运行setupDeliveryItemsTable()。
我遇到的问题是有大量行,这会大大减慢页面速度,有时会导致浏览器崩溃。
我可以做些什么来优化此代码,以便仍然允许可编辑的项目,而不会在服务器上如此困难。
我应该使用类似的东西:
$(document).on('click'
检测点击应该是一个可编辑的字段,然后调用可编辑的函数并链接一个点击事件,还是有更好的方法?
答案 0 :(得分:0)
感谢您的回复,我可以使用knockout.js点击处理程序进行一些更改。我还必须更改jeditable以使用按钮来触发可编辑事件。通常我使用jeditable来使所有表格都可编辑。 Jeditable在调用它时会这样做,它会处理所点击项目的点击事件。
这是我的最终HTML
<table class="table table-striped table-bordered table-hover tablesorter" id="deliveryItemsTable" data-bind="visible: showTable">
<thead>
<tr class="title1">
<td colspan="100%">Delivery Items</td>
</tr>
<tr class="title2">
<th class="header">Created On</th>
<th class="header">Company</th>
<th class="header">Item Number</th>
<th class="header">Phone Number</th>
<th>Price</th>
<th class="header">Location</th>
<th class="header">Notes</th>
<th class="header">Delivery Driver</th>
<th class="header">Status</th>
<th class="header nowrap"></th>
</tr>
</thead>
<tbody data-bind="foreach: deliveryItems">
<tr data-bind="attr: {id: 'row_' + id }">
<td data-bind="text: created_on"></td>
<td data-bind="text: company_name"></td>
<td data-bind="text: product_number_company"></td>
<td data-bind="text: client_phone_number"></td>
<td data-bind="text: formatCurrency(price_to_display)"></td>
<td>
<span data-bind="text: location, attr: {id: 'edit-delivery_items-' + id + '_location' }"></span>
<button data-bind="click: $root.editLocation" class="btn btn-default btn-xs" title="Edit"><i class="glyphicon glyphicon-edit"></i></button>
</td>
<td>
<span data-bind="text: notes, attr: {id: 'edit-delivery_items-' + id + '_notes' }"></span>
<button data-bind="click: $root.editNotes" class="btn btn-default btn-xs" title="Edit"><i class="glyphicon glyphicon-edit"></i></button>
</td>
<td>
<span data-bind="text: delivered_by_text, attr: {id: 'edit_select-delivery_items-' + id + '_delivered_by' }"></span>
<button data-bind="click: $root.editDeliveryDriver" class="btn btn-default btn-xs" title="Edit"><i class="glyphicon glyphicon-edit"></i></button>
</td>
<td data-bind="html: status_labels"></td>
<td class="center"><span class="btn-group">
<button data-bind="click: $root.markAsDelivered, visible: $root.canMarkComplete" class="btn btn-default" title="Mark as delivered"><i class="glyphicon glyphicon-check"></i></button>
<a data-bind="attr: {href: 'index.php?action=editDeliveryItem&id=' + id }, visible: $root.canEdit" class="btn btn-default" title="Edit"><i class="glyphicon glyphicon-edit"></i></a>
</span></td>
</tr>
</tbody>
</table>
<div class="alert alert-info" data-bind="visible: showLoadingNotice">
Loading...
</div>
<div id="deliveryItemsTableUpdateNotice"></div>
这是我提出的处理表格和可编辑项目的JS:
var deliveryItemsModel = function () {
var self = this;
self.deliveryItems = ko.observableArray();
self.showTable = ko.observable(false);
self.showLoadingNotice = ko.observable(true);
self.canMarkComplete = ko.observable(false);
self.canEdit = ko.observable(false);
self.getDeliveryItems = function () {
$.getJSON( SITE_URL + '/ajax.php?action=returnDeliveryItemsTableJSON', function(retrievedData) {
self.updateData(retrievedData);
//console.log('back out');
});
};
self.getDeliveryItemsForToday = function () {
var todaysDate = new Date();
$.getJSON( SITE_URL + '/ajax.php?action=returnDeliveryItemsTableJSON&status=not-delivered&scheduled_for_delivery_on=' + (todaysDate.getMonth() + 1) + '/' + todaysDate.getDate() + '/' + todaysDate.getFullYear(), function(retrievedData) {
self.updateData(retrievedData);
//console.log('back out');
});
};
self.updateData = function (data) {
self.deliveryItems(data);
self.showLoadingNotice(false);
self.showTable(true);
//console.log(data);
// We moved this to functions.js since we use it multiple times
setupDeliveryItemsTable();
};
self.replaceData = function (data) {
self.showLoadingNotice(true);
self.showTable(false);
self.updateData(data);
};
/* Click Functions */
self.markAsDelivered = function (deliveryItem) {
bootbox.confirm('Are you sure you want to mark this as delivered?', function(result) {
if ( result == true ) {
self.showLoadingNotice(false);
self.showTable(true);
jQuery.post(SITE_URL + '/ajax.php?action=markDeliveryItemDelivered&id=' + deliveryItem.id, function(data) {
// Trigger the search function to refresh the table
$('#searchDeliveryItemsForm').submit();
});
}
});
};
self.editLocation = function (deliveryItem) {
handleEditOnClick('delivery_items', deliveryItem.id, 'location');
};
self.editNotes = function (deliveryItem) {
handleEditOnClick('delivery_items', deliveryItem.id, 'notes');
};
self.editDeliveryDriver = function (deliveryItem) {
handleEditDeliveryDriverOnClick('delivery_items', deliveryItem.id, 'delivered_by');
};
};
/* Functions we use for the model above */
function handleEditOnClick(table, dbID, name) {
var options = {
event : 'edit',
id : 'cssID',
cancel : '<button class="btn btn-default btn-sm editable-cancel" type="button"><i class="glyphicon glyphicon-remove"></i></button>',
submit : '<button class="btn btn-primary btn-sm editable-submit" type="submit"><i class="glyphicon glyphicon-ok"></i></button>',
indicator : indicatorImage,
tooltip : 'Click to edit...',
style : 'display: inline;',
width : 'none',
type : 'textarea'
};
$('#edit-' + table + '-' + dbID + '_' + name).editable(
SITE_URL + '/ajax.php?action=updateitem&table=' + table + '&item=' + name + '&id=' + dbID,
options
).trigger('edit');
};
function handleEditDeliveryDriverOnClick(table, dbID, name) {
var options = {
event : 'edit',
id : 'cssID',
cancel : '<button class="btn btn-default btn-sm editable-cancel" type="button"><i class="glyphicon glyphicon-remove"></i></button>',
submit : '<button class="btn btn-primary btn-sm editable-submit" type="submit"><i class="glyphicon glyphicon-ok"></i></button>',
indicator : indicatorImage,
tooltip : 'Click to edit...',
style : 'display: inline;',
width : 'none',
type : 'select',
loadurl : SITE_URL + '/ajax.php?action=getDeliveryDriversJSON' + '&id=' + dbID
};
$('#edit_select-' + table + '-' + dbID + '_' + name).editable(
SITE_URL + '/ajax.php?action=updateDeliveryDriverByID&id=' + dbID,
options
).trigger('edit');
};
var viewModel = new deliveryItemsModel();
ko.applyBindings( viewModel );
viewModel.canMarkComplete(true);
viewModel.canEdit(true);
viewModel.getDeliveryItems();
我不确定这是否会对其他人有所帮助,但我认为我最终会分享对我有用的东西。
如果有人认为有任何方法可以进一步优化,请告诉我。