Javascript - 清空对象而不是创建新对象

时间:2015-01-25 07:57:09

标签: javascript jquery ajax scope

每次点击后,我打算清空对象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;
                    }

            });
    });

}

2 个答案:

答案 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">&times;</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');
        }
    });
});

警告上述代码包含对两个未定义的全局变量(columnIndexrowIndex)的引用。我不知道它们来自哪里,我只是从你的代码中提取它们。由于多种原因维护全局变量是一个坏主意,最大的原因是许多令人讨厌的错误可以追溯到全局变量。尝试通过函数结果或局部变量替换这些引用。

推荐这种情况是像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时就创建了一个对象,所以没有转义它。

如果我错过了你的意图,请澄清你的问题。