如何在不覆盖相同键值的情况下更新 localStorage 中的数组?

How do you update an array in localStorage without overwriting same-key values?

提问人:TraktorJack 提问时间:4/29/2021 最后编辑:CerbrusTraktorJack 更新时间:4/29/2021 访问量:2317

问:

我正在尝试从本地存储中检索 arrray,使用相同的键附加一个新数组,然后将其粘贴回存储中。但是,我似乎无法让它工作,我尝试将我的数组转换为对象,并将对象转换为数组(我是编程新手,所以我不确定最好的方法是什么。我还尝试使用扩展运算符、object.entries()、object.assign() 和其他一些无意义的选项。

编辑:

保存到存储的是用户输入值:"[[["name","bob ross"],["about","Painter"]]]"

我希望用户能够添加“Bilbo Baggins”作为名称,添加“Hobbit”作为大约,那么存储应该如下所示:

"[[["name","bob ross"],["about","Painter"]]], [[["name","Bilbo Baggins"],["about","Hobbit"]]]"

任何帮助将不胜感激!这是我的代码:

//============= Allows writing to LocalStorage without overwrite ==========================
submitbtn.addEventListener('click', function () {
    const oldInfo = JSON.parse(localStorage.getItem('data'));  // Retrieves info from storage to make it writeable
    console.log('old Info: ', oldInfo); // Shows user what's currently saved in oldInfo
    const newInfo = {};
            newInfo.name = name.value; // Name and about are user input values
            newInfo.about = about.value;
    let array = Object.entries(newInfo); // Turns newInfo into an array
    console.log('new info: ', newInfo);
    oldInfo.push(array); // Appends newInfo to oldInfo without overwriting oldInfo data
    console.log(oldInfo);
    localStorage.setItem('data', JSON.stringify(oldInfo)); // Saves newly updated array to localStorage
});
JavaScript 数组 JSON 对象

评论

3赞 Cerbrus 4/29/2021
目前还不清楚你到底期望发生什么?您能否为您的问题添加一个示例,包括之前的存储状态、新信息是什么以及之后您期望在存储中存储的内容?(所以,只是简单的数据,你需要发生什么?
2赞 Cerbrus 4/29/2021
在问题中,@TraktorJack。
0赞 Cerbrus 4/29/2021
没关系。嗯,据我所知,你的代码应该已经完全按照你的要求做了......您是否遇到任何控制台错误?
0赞 TraktorJack 4/29/2021
不,它只是没有附加新值。它只是覆盖它们
0赞 tevemadar 4/29/2021
预期的输出应该有双括号“inside”,而不是三括号。您是否知道 JSON 也可以存储对象,而不仅仅是列表?它可能是"[[["name","bob ross"],["about","Painter"]], [["name","Bilbo Baggins"],["about","Hobbit"]]]"[{"name":"Bob Ross","about":"Painter"},{"name":"Bilbo Baggins","about":"Hobbit"}]

答:

2赞 Alex 4/29/2021 #1

我建议你保留一个对象格式,因为你似乎只需要更新属性,而不是存储。

这样,您只需使用 oldInfo 对象并使用 spread 运算符从中创建新对象(并摆脱转换)来更新您的商店:

假设你把它放在你的 localStorage(字符串化)中:

const initialInfo = {
   name: '',
   about: ''
};

然后你可以简单地做

const oldInfo = JSON.parse(localStorage.getItem('data'));
localStorage.setItem(
   'data',
   JSON.stringify({ ...oldInfo, name: name.value, about: about.value })
);

这是 Object.assign 的语法糖,在我看来,对阅读指令有很大帮助。 在这里,这意味着您正在“克隆”oldInfo 对象,并将新值分配给放置在其后面的列出的属性。...

编辑:

问题编辑后;如果要在一个数组中存储多个对象,则应使用数组扩展运算符。这样:

const oldInfo = JSON.parse(localStorage.getItem('data'));
// oldInfo = [{ name: 'example', about: 'test' }];

const yourNewObject = {
   value: name.value,
   about: about.value
};
localStorage.setItem(
   'data',
   JSON.stringify([ ...oldInfo, yourNewObject ])
);

这样,您将向数组添加一个对象

评论

1赞 Cerbrus 4/29/2021
不,查看编辑,OP 想要添加条目,而不是替换它们
0赞 Alex 4/29/2021
谢谢,我写了答案,没有看到打字:)期间的编辑
0赞 TraktorJack 4/29/2021
谢谢@Alex!Cerbrus 的回答更适合我的需求,但感谢您的帮助:)
2赞 Cerbrus 4/29/2021 #2

我已经清理了代码。

您的代码应该可以工作,只是在第一次加载时缺少一些错误处理。

// Mock data
const name = { value: 'Foo name' };
const about = { value: 'Bar about' };
const submitbtn = document.getElementById('submit');

// Fake localStorage to make it work in the snippet
mockLocalStorage = {
  getItem: (key) => this[key],
  setItem: (key, value) => this[key] = value
};

submitbtn.addEventListener('click', function() {
  // Make sure we get -something- back in case this is the first time we're accessing the storage.
  const oldInfo = JSON.parse(mockLocalStorage.getItem('data') || '[]');
  console.log('Before', oldInfo);

  // The creation of the new object can be done in 1 step.  
  const array = Object.entries({
    name: name.value,
    about: about.value
  });

  oldInfo.push(array); // Appends newInfo to oldInfo without overwriting oldInfo data
  console.log('After', oldInfo);
  mockLocalStorage.setItem('data', JSON.stringify(oldInfo));
});
<button id="submit" type="button">Submit!</button>