繁体   English   中英

从localStorage中删除特定项目

[英]Removing specific item from localStorage

我正在使用jQuery / JS向localStorage添加一些项目,这很好但是在尝试删除数组中的特定项目时(如果它是相同的项目)证明是困难的。

在我的控制台日志中(用于测试)它似乎清除了[对象],但它没有更新密钥。 也许我的等级制度错了......任何想法?

//
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');
    });
});

这是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
   }
]

在此输入图像描述

在使用“foreach”迭代时,切勿在数组中添加/删除元素。 相反,试试这个:

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);
            }
        }
    }
});

另一种更优雅的方法是使用ES6 filter():

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

此外,您将localData与文字字符串'null'进行比较,这是毫无意义的。 你的第二个条件 - if (!localData)在这种情况下是足够的,并将正确处理它。

问题在于你的拼接方法用法。 请注意,根据MDN, splice会修改数组并返回一个包含已删除元素的新数组。 因此,当使用循环并尝试删除某些元素时,拼接将使元素移位。 这是因为通过数组递增迭代,当你拼接它时,数组被修改到位,所以项目被“移位”,你最终跳过了一些迭代。 向后循环修复了这个问题,因为你没有在你拼接的方向上循环。

解决方案1

拼接时向后循环。

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

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

在这里工作bin链接。

解决方案2

生成新数组通常更快,而不是修改现有数组。 所以,你的代码看起来像

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

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

工作箱链接在这里 之后,在获取和设置localStorage时没有问题。

你写的代码中有一个额外的错误

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);
        }
    }
}

什么时候应该

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);
        }
    }
}

也可以写

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

您正在通过拼接来改变阵列。 正在重写的唯一localstorage项是保留在数组中的那些。

因此,从阵列中拼接对象时,请从存储中删除该项。

$.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');
                    }
                }
            }
        }
    });

好。 你要踢自己。 第一次从localStorage中提取时, getItem方法返回一个null值,但是你试图将它与一个字符串'null' ,引号)进行比较。 失败。 我将localData == 'null'更改为localData == null

表达式的第二部分试图看到实际定义了从getItem返回的值,这很好。 我通过typeof将其改为更明确。

显式变量声明也有帮助。

 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