简体   繁体   English

从localStorage中删除特定项目

[英]Removing specific item from localStorage

I'm adding some items to localStorage, using jQuery/JS, which is all fine but in trying to remove a specific item within the array (if it's the same item) is proving difficult. 我正在使用jQuery / JS向localStorage添加一些项目,这很好但是在尝试删除数组中的特定项目时(如果它是相同的项目)证明是困难的。

In my console logs (for testing) it seems to clear the [Object] but it's not updating the key. 在我的控制台日志中(用于测试)它似乎清除了[对象],但它没有更新密钥。 Perhaps my hierarchy is wrong... any ideas? 也许我的等级制度错了......任何想法?

//
function addToStorage(elem, name) {

    localData = localStorage.getItem(name + 'Storage');
    var typefaces;

    if (localData == 'null' || !localData) {
        typefaces = [];
    } else {
       typefaces = JSON.parse(localData);
    }

    typefaceID = elem.find('input').val();
    typefaceName = elem.find('input').attr('data-name');
    typefacePrice = elem.find('input').attr('data-price');
    typefaceQty = 1;

    $.each(typefaces, function(index, value) {
        if (value !== null) {
            if (value.id == typefaceID) {
                if (name == 'drf') {
                    //console.log(index);
                    //console.log(typefaces);
                    typefaces.splice(index, 1);
                    //console.log(typefaces);
                }
            }
        }
    });

    typefaces.push({
        'id': typefaceID,
        'name': typefaceName,
        'price': typefacePrice,
        'qty': typefaceQty
    });

    localStorage.setItem(name + 'Storage', JSON.stringify(typefaces));

}

//
$(document).on('click', 'summary.cart td.font', function(e) {
    e.preventDefault();
    addTo = $(this);
    addTo.each(function() {
        addToStorage(addTo, 'drf');
    });
});

This is an example of the localData once it's been added to. 这是localData一旦被添加到的一个例子。

[  
   {  
      "id":"dr-raymond-desktop-40374",
      "name":"DR-Raymond",
      "format":"Desktop (OTF)",
      "price":"15.00",
      "qty":1
   },
   {  
      "id":"dr-raymond-webfont-39949",
      "name":"DR-Raymond",
      "format":"Webfont (WOFF)",
      "price":"15.00",
      "qty":1
   }
]

在此输入图像描述

Never add/remove elements from an array while iterating over it using "foreach". 在使用“foreach”迭代时,切勿在数组中添加/删除元素。 Instead, try this: 相反,试试这个:

for (index = typefaces.length - 1; index >= 0; index--){
    value = typefaces[index];
    if (value !== null) {
        if (value.id == typefaceID) {
            if (name == 'drf') {
                typefaces.splice(index, 1);
            }
        }
    }
});

Another way to do this more elegantly is by using ES6 filter(): 另一种更优雅的方法是使用ES6 filter():

typefaces = typefaces.filter(value => !(value && value.id == typefaceID && name == "drf"));

Also, you are comparing localData to the literal string 'null' which is kind of pointless. 此外,您将localData与文字字符串'null'进行比较,这是毫无意义的。 Your second condition - if (!localData) is enough in this case, and will handle it properly. 你的第二个条件 - if (!localData)在这种情况下是足够的,并将正确处理它。

The problem lies in your splice method usage. 问题在于你的拼接方法用法。 Note that, according to MDN splice modifies the array in place and returns a new array containing the elements that have been removed. 请注意,根据MDN, splice会修改数组并返回一个包含已删除元素的新数组。 So when using a loop and trying to remove the some elements, splice will make shifting of elements. 因此,当使用循环并尝试删除某些元素时,拼接将使元素移位。 This is because iterating incrementally through the array, when you splice it, the array is modified in place, so the items are "shifted" and you end up skipping the iteration of some. 这是因为通过数组递增迭代,当你拼接它时,数组被修改到位,所以项目被“移位”,你最终跳过了一些迭代。 Looping backwards fixes this because you're not looping in the direction you're splicing. 向后循环修复了这个问题,因为你没有在你拼接的方向上循环。

Solution 1 解决方案1

Loop backwards while splicing. 拼接时向后循环。

for(var i = typefaces.length; i--;)
{
            if (typefaces[i] !== null) 
            {

                if (typefaces[i] == typefaceID) 
                {
                        typefaces.splice(i, 1);
                }
            }
 }

Working bin link here . 在这里工作bin链接。

Solution 2 解决方案2

Its usually faster to generate a new array instead of modifying the existing one. 生成新数组通常更快,而不是修改现有数组。 So, your code will look like 所以,你的代码看起来像

ty = [];
   $.each(typefaces, function(index, value) {
        if (value !== null) {

            if (value.id != typefaceID) {
                    ty.push(value);
            }
        }
    });
  typefaces = ty;

Working bin link is here . 工作箱链接在这里 After that there is no problem found in getting and setting your localStorage. 之后,在获取和设置localStorage时没有问题。

You have an additional error in your code, you write 你写的代码中有一个额外的错误

if (value !== null) {
    if (value.id == typefaceID) {
        // name will always have the value drf 
        // since you pass it in your function
        // when you call it addToStorage(addTo, 'drf');
        if (name == 'drf') {
            typefaces.splice(index, 1);
        }
    }
}

when it should be 什么时候应该

if (value !== null) {
    if (value.id == typefaceID) {
        // here the comparison should be between value.name and name
        if (value.name == name) {
            typefaces.splice(index, 1);
        }
    }
}

which can be also written 也可以写

if (value !== null) {
    if (value.id == typefaceID && value.name == name) {
            typefaces.splice(index, 1);
    }
}

You are mutating the array by splicing it. 您正在通过拼接来改变阵列。 The only localstorage items that are being re written are the ones that are left in the array. 正在重写的唯一localstorage项是保留在数组中的那些。

So delete the item from the storage when you splice an object from the array. 因此,从阵列中拼接对象时,请从存储中删除该项。

$.each(typefaces, function(index, value) {
        if (value !== null) {
            if (value.id == typefaceID) {
                if (name == 'drf') {
                    //console.log(index);
                    //console.log(typefaces);
                    var removedTypeFace = typefaces.splice(index, 1);
                    //console.log(typefaces);

                    if(removedTypeFace) {
                        localStorage.removeItem(removedTypeFace.name + 'Storage');
                    }
                }
            }
        }
    });

OK. 好。 You're going to kick yourself. 你要踢自己。 The first time you pull from localStorage, the getItem method DOES return a null value, but you're trying to compare it to a string ( 'null' , in quotes). 第一次从localStorage中提取时, getItem方法返回一个null值,但是你试图将它与一个字符串'null' ,引号)进行比较。 Fail. 失败。 I changed localData == 'null' to localData == null . 我将localData == 'null'更改为localData == null

The second part of the expression tries to see the value returned from getItem is actually defined, which is good. 表达式的第二部分试图看到实际定义了从getItem返回的值,这很好。 I changed that to be more explicit, by way of typeof . 我通过typeof将其改为更明确。

Explicit variable declarations help, too. 显式变量声明也有帮助。

 function addToStorage(elem, name) { var localData = localStorage.getItem(name + 'Storage'); var typefaces; if (localData == null || typeof(localData) == 'undefined') { typefaces = []; } else { typefaces = JSON.parse(localData); } var typefaceID = elem.find('input').val(); var typefaceName = elem.find('input').attr('data-name'); var typefacePrice = elem.find('input').attr('data-price'); var typefaceQty = 1; $.each(typefaces, function(index, value) { if (value !== null) { if (value.id == typefaceID) { if (name == 'drf') { //console.log(index); //console.log(typefaces); typefaces.splice(index, 1); //console.log(typefaces); } } } }); typefaces.push({ 'id': typefaceID, 'name': typefaceName, 'price': typefacePrice, 'qty': typefaceQty }); localStorage.setItem(name + 'Storage', JSON.stringify(typefaces)); } // jQuery(document).on('click', 'summary.cart td.font', function(e) { e.preventDefault(); addTo = $(this); addTo.each(function() { addToStorage(addTo, 'drf'); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <summary class='cart'><table><tr> <td class='font' >Click Here for Item 1 <input data-name='abc' data-price='2.00' value="Item 1" /></td></tr> <tr> <td class='font' >Click Here for Item 2 <input data-name='def' data-price='4.00' value="Item 2" /></td></tr></table> </summary> 

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

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