开发者问题收集

无法使用 localStorage 读取未定义的属性推送

2014-11-13
4569

我有一个动态列表视图,用于显示商店的各种优惠。我希望用户在从列表视图中选择时能够保存这些优惠,以便使用 localStorage 生成已保存的优惠功能。

我已设法达到可以通过选择列表视图中的优惠来保存 1 个优惠的程度。

在选择列表视图行时,它会从该特定选择中获取数据属性并填充一个数组,然后将其传递给 localStorage。

JS

$("#offers ul").on("click", ">li", function(event, ui) {                                                                                                                                                                           
    var offertitle = $(this).closest('li').attr('data-offer-title'); 
    var offerdesc = $(this).closest('li').attr('data-offer-desc');
    var offerexpiry = $(this).closest('li').attr('data-offer-expiry'); 

    if (offerObject === null) {
        offerObject = [];
    }   

    var offerObject= {"offer":[ 
        { 
            'offertitle': offertitle, 
            'offerdesc': offerdesc,
            'offerexpiry': offerexpiry
        }
    ]};

    var offers = localStorage.setItem('offerObject', JSON.stringify(offerObject));
    offers.push(offerObject);   
});     

var retrievedOffers = JSON.parse(localStorage.getItem('offerObject'));

var output2='';
for (var i in retrievedOffers.offer) {
    output2+="<li>" + retrievedOffers.offer[i].offertitle + " " + retrievedOffers.offer[i].offerdesc + " " + retrievedOffers.offer[i].offerexpiry+"</li>";
}
$('#savedofferlist').html(output2).listview().listview('refresh');

我现在正尝试将列表视图的更多优惠推送到 offerObject 变量中,以便使用 localStorage 根据用户的选择生成已保存优惠的列表视图。

当我尝试从列表视图中进行选择时,我收到 JS 错误“无法读取未定义的属性推送”。​​即使存在错误,它仍会显示我从列表中选择的 1 个选项。

我是否必须分解 .push(offerObject) 而不是推送整个变量?

如能得到任何帮助,我们将不胜感激。

1个回答

localStorage 上的 setItem() 方法具有 void 返回类型( docs ),因此您尝试在“无”上使用 push()

您需要从本地存储中获取列表(在插入之前或之后)...并且“附加”到本地,如果您在“设置”之前获取了它。

//Option 1: set then fetch
localStorage.setItem('offerObject', JSON.stringify(offerObject));
var offers = JSON.parse(localStorage.getItem('offerObject'));


//Option 2: fetch, set then append
var offers = JSON.parse(localStorage.getItem('offerObject'));
localStorage.setItem('offerObject', JSON.stringify(offerObject));

//append the current object to the previously fetched list
offers.push(offerObject);

更新

仔细查看代码,似乎您的 JSON 结构与我认为您希望的不符。从根本上讲,您希望存储的对象“offerObject”实际上是一个数组(列表),而不是一个对象(例如映射)。

因此,您 总是 需要先从本地存储中获取当前列表,将其附加到其中,然后将其设置回去。

我已经修改了您的代码,以更好地反映我认为您正在尝试做的事情(这里有一个 JSFiddle ,您可以尝试一下:

//get your values (I hard coded this for my test)
var offertitle = "This is the offer title id:[" + new Date().getTime() + "]";
var offerdesc = "This is the offer description";
var offerexpiry = "This is the offer expiry " + new Date();

//create your offer object (I just made this a simple 3 key/value pair)
var offer = {
  "offertitle": offertitle,
  "offerdesc": offerdesc,
  "offerexpiry": offerexpiry
};

var offers = [];//initialize an empty array for all of the offers

//get the current list of offers (if any)
var existingOffers = localStorage.getItem('offers');
if(existingOffers != null){
  offers = JSON.parse(existingOffers);
}

//append the new item
offers.push(offer);

//reset the local storage
localStorage.setItem('offers', JSON.stringify(offers));

console.log('Offers: ' + offers.length + '\n\n' + JSON.stringify(offers));
scunliffe
2014-11-13