简体   繁体   English

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

[英]Javascript - Emptying Object instead of Creating new Object

After each click, I intend to empty object editProductList . 每次单击之后,我打算清空对象editProductList My code below is instead creating an additional new object editProductList instead of emptying the original editProductList . 我在下面的代码改为创建其他新对象editProductList而不是清空原始editProductList How do I ensure I'm emptying editProductList instead of creating a new editProductList after clicking it once more? 如何确保我再次单击后要清空editProductList而不是创建新的editProductList

After the first clicking on the 'devices' column, then #edit_product_add_btn , 首次点击'devices'列后,然后#edit_product_add_btn

I'm logging: 我正在记录:

product name, qty:  Remote Tag 6

After the second clicking on the 'devices' column, then #edit_product_add_btn , the previous object remains, and it updates both the original object and new one at the same time 第二次单击'devices'列之后,然后#edit_product_add_btn ,保留了先前的对象,并且它同时更新了原始对象和新对象

product name, qty:  Remote Tag 7
product name, qty:  Remote Tag 6

Why is it creating an additional object of the same editProductList instead of emptying the original one? 为什么要创建一个具有相同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;
                    }

            });
    });

}

After deconstructing your code example it became clear that you want to maintain a shopping cart. 解构了代码示例之后,很明显,您想要维护一个购物车。

  • If the user adds a product that also is already in the cart, it should simply increase the quantity of the existing item. 如果用户添加的商品也已经在购物车中,则应该简单地增加现有商品的数量。
  • If the user adds a new product, it should append it to the cart. 如果用户添加了新产品,则应将其添加到购物车中。
  • In both cases the screen should be updated accordingly. 在这两种情况下,都应相应更新屏幕。

So there are two tasks here. 因此,这里有两个任务。 Maintain a list and update the screen. 维护列表并更新屏幕。

For updating the screen it is helpful to use an HTML templating library. 对于更新屏幕,使用HTML模板库很有帮助。 This helps code readability and reduces the risk surface (no more manual HTML building from strings = less XSS risk). 这有助于提高代码的可读性并减少风险表面(不再需要通过字符串来构建手动HTML,而是减少了XSS风险)。 I used Mustache.js in the following example. 在以下示例中,我使用了Mustache.js。

It is also helpful to separate the tasks so function size stays manageable. 分离任务也很有帮助,因此功能大小保持可管理性。

Note how I use a custom jQuery event ( dataUpdated ) to decouple screen updating from list maintenance: 注意我如何使用自定义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');
        }
    });
});

Warning The above code contains references to two undefined global variables ( columnIndex and rowIndex ). 警告上面的代码包含对两个未定义的全局变量( columnIndexrowIndex )的引用。 I have no idea where they come from, I just carried them over from your code. 我不知道它们来自哪里,我只是将它们从您的代码中继承下来。 It is a bad idea to maintain global variables for a number of reasons, the biggest one being that many nasty bugs can be traced back to global variables. 维护全局变量是一个坏主意,其原因有很多,最大的原因是可以将许多讨厌的错误追溯到全局变量。 Try to replace those references, either by function results or by local variables. 尝试用函数结果或局部变量替换那些引用。

Recommendation This situation is the perfect use case of MVVM libraries like Knockout.js. 建议这种情况是MVVM库(如Knockout.js)的完美用例。 They are designed to completely take over all UI updating for you, so all you need to do is to maintain the data model of the shopping cart. 它们旨在完全为您接管所有UI更新,因此您所需要做的就是维护购物车的数据模型。 You might want to consider switching. 您可能要考虑切换。

It's not so clear what you are trying to do. 目前尚不清楚您要做什么。

You seem to be defining a click handler as a method of EditableGrid. 您似乎正在将点击处理程序定义为EditableGrid的方法。 So the user will need to click something for the ajax call to be executed, and then click #edit_product_add_btn to load the results into a variable which is local to the first handler? 因此,用户将需要单击某些内容以执行ajax调用,然后单击#edit_product_add_btn将结果加载到第一个处理程序本地的变量中? Presumably you are doing something with editProductList after the ajax call comes back, if not loading it at all is pointless, since you can't access it from anywhere else. 假定您在ajax调用返回后正在使用editProductList进行操作,如果根本不加载它是没有意义的,因为您无法从其他任何地方访问它。 Perhaps you want this.editProductList instead, so it is accesible from the rest of the "class"? 也许您想要使用this.editProductList ,因此它可以在“类”的其余部分使用吗?

Are you sure you don't mean to do something like this? 您确定您不是要这样做吗?

EditableGrid.prototype.mouseClicked = function(e) {

  var self = this;

  $.ajax({
    //...
    success: function(response) {
      self.editProductList = JSON.parse(response);
    }
  });
};

About mutating the current object instead of creating a new one: I don't think you gain much from trying to do this. 关于更改当前对象而不是创建一个新对象:我认为您不会从尝试这样做中受益。 The old object will be garbage collected as soon as the variable points to the new one. 一旦变量指向新对象,旧对象将被垃圾回收。 You are creating an object as soon as you do JSON.parse, so there's no escaping that. 您只要执行JSON.parse,就可以创建一个对象,因此无法逃避。

If I missundersood your intentions, please clarify your question. 如果我听错了您的意图,请澄清您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM