每次点击后,我打算清空对象editProductList
。我的下面的代码是创建一个额外的新对象editProductList
而不是清空原始editProductList
。如何确保我在清空后再editProductList
而不是创建新的editProductList
?
首次点击'devices'
列,然后点击#edit_product_add_btn
,
我正在记录:
product name, qty: Remote Tag 6
第二次点击'devices'
列,然后#edit_product_add_btn
后,前一个对象仍然存在,并同时更新原始对象和新对象
product name, qty: Remote Tag 7
product name, qty: Remote Tag 6
为什么要创建相同editProductList
的其他对象而不是清空原始对象?
EditableGrid.prototype.mouseClicked = function(e) {
var editProductList = {};
$.ajax({
//...
success: function(response) {
editProductList = JSON.parse(response);
console.log('editProductList direct from DB: ', editProductList);
//adding products into editProductList
$('#edit_product_add_btn').on('click', function(e) {
var in_editProductList = false;
for (var product in editProductList) {
if (editProductList.hasOwnProperty(product)) {
if (editProductList[product].name === productType) {
//...
console.log('product name, qty: ', editProductList[product].name, editProductList[product].qty);
in_editProductList = true;
break;
}
}
}
if (in_editProductList === false) {
//...
var new_product_obj = { name: productType, qty: qty };
editProductList[Object.size(editProductList)] = new_product_obj;
}
});
});
}
答案 0 :(得分:1)
解构您的代码示例后,很明显您想要维护购物车。
所以这里有两个任务。维护列表并更新屏幕。
要更新屏幕,使用HTML模板库会很有帮助。这有助于编码可读性并降低风险表面(不再需要从字符串构建手动HTML =减少XSS风险)。我在下面的例子中使用了Mustache.js.
分离任务也很有帮助,因此功能大小可以管理。
请注意我如何使用自定义jQuery事件(dataUpdated
)将屏幕更新与列表维护分离:
$(function () {
var editProductList = [];
var productListItems = Mustache.parse('{{#.}}<li class="list-group-item"><span class="badge">{{qty}}</span>{{name}}<button type="button" class="close" aria-hidden="true">×</button></li>{{/.}}');
EditableGrid.prototype.mouseClicked = function (e) {
if (this.getColumnName(columnIndex) == 'devices') {
$.post('get_requested_devices.php', {
table: this.name,
request_id: this.getRowId(rowIndex)
})
.done(function (response) {
editProductList = response;
$('#edit_product_list').trigger("dataUpdated");
});
}
};
$('#edit_product_list').on("dataUpdated", function () {
var listItems = Mustache.render(productListItems, editProductList);
$('#edit_product_list').empty().append(listItems);
});
$('#edit_product_add_btn').on('click', function (e) {
var qty = parseInt($('#edit_product_qty').val().trim(), 10);
var name = $('#edit_product_type').text().trim();
var existingProduct;
if (qty > 0) {
existingProduct = $.grep(editProductList, function (product) {
return product.name === name;
});
if (existingProduct) {
existingProduct.qty += qty;
} else {
editProductList.push({
name: name,
qty: qty
});
}
$('#edit_product_list').trigger("dataUpdated");
} else {
alert('Enter a number greater than 0');
}
});
});
警告上述代码包含对两个未定义的全局变量(columnIndex
和rowIndex
)的引用。我不知道它们来自哪里,我只是从你的代码中提取它们。由于多种原因维护全局变量是一个坏主意,最大的原因是许多令人讨厌的错误可以追溯到全局变量。尝试通过函数结果或局部变量替换这些引用。
推荐这种情况是像Knockout.js这样的MVVM库的完美用例。它们旨在完全接管所有UI更新,因此您需要做的就是维护购物车的数据模型。您可能需要考虑切换。
答案 1 :(得分:0)
你要做的事情还不是很清楚。
您似乎将单击处理程序定义为EditableGrid的方法。因此,用户需要单击某个内容才能执行ajax调用,然后单击#edit_product_add_btn
将结果加载到第一个处理程序本地的变量中?据推测,在ajax调用返回后,你正在使用editProductList
做一些事情,如果不加载就没有意义,因为你无法从其他任何地方访问它。也许您想要this.editProductList
,所以它可以从“类”的其余部分访问?
你确定你不打算做这样的事吗?
EditableGrid.prototype.mouseClicked = function(e) {
var self = this;
$.ajax({
//...
success: function(response) {
self.editProductList = JSON.parse(response);
}
});
};
关于改变当前对象而不是创建一个新对象:我认为你不会因为尝试这样做而获得太多收益。一旦变量指向新对象,旧对象将被垃圾收集。你在做JSON.parse时就创建了一个对象,所以没有转义它。
如果我错过了你的意图,请澄清你的问题。