localStorage中的JS数据仅保存在一个键值对中

时间:2014-01-16 00:04:57

标签: javascript json html5 local-storage

我正在尝试编写一个简单的应用程序,以尝试了解HTML5的localStorage。我(以为我)已经成功创建了一个表单来获取数据并将其存储在localStorage(使用JSON.stringify),然后在页面上显示(在JSON.parse之后)。然后我转到了如何删除特定项目并意识到我认为我正在错误地存储数据,因为我只有一个键,值对,当我认为每个条目应该有一个。所以调用localStorage.removeItem(key)只删除了我的所有数据。我需要帮助整理如何分别存储每个条目,以便逐个删除它们。

HTML:

<form id="sme-submission" name="sme-submission">
    <ul class="no-list-style">
        <li>
        <h2>Add an SME</h2>
        </li>
        <li>
            <label for="firstname">First Name:</label><br />
            <input type="text" id="firstname"/>
        </li>
        <li>
            <label for="lastname">Last Name:</label><br />
            <input type="text" id="lastname"/>
        </li>
        <li>
            <label for="email">Email:</label><br />
            <input type="email" id="email"/>
        </li>
        <li>
            <label for="subject">Subject:</label><br />
            <input type="text" id="subject"/>
        </li>
        <li>
            <input type="submit" value="Save" id="btnSave" class="btn btn-success"/>
        </li>
    </ul>
</form>

<div id="list-display">

</div>

<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>

JS:

var rolodex = localStorage.getItem('rolodex'); //load stored data if there is any

window.onload = function() {
    rolodex = JSON.parse(rolodex);
    if(rolodex === null) { //if no data, initialize an empty array
        rolodex = [];
    } else {
    console.log(rolodex);
    }


    var btnSave = document.getElementById('btnSave');
    btnSave.addEventListener('click', Add, false);

    List();
};    

var Add = function() {
    var SME = JSON.stringify({
        firstname:document.getElementById('firstname').value,
        lastname:document.getElementById('lastname').value,
        email:document.getElementById('email').value,
        subject:document.getElementById('subject').value,

    });

    rolodex.push(SME);
    localStorage.setItem('rolodex', JSON.stringify(rolodex));

for (var key in SME) {
    var person = JSON.parse(SME[key]);
    var div = document.getElementById('list-display').lastChild;
    div.innerHTML = div.innerHTML + "<div class='sme-entry'><ul class='no-list-  style'><li><h3>"+person.subject+"<h3></li><li>"+person.firstname+" "+person.lastname+"</li><li>"+person.email+"</li></ul></div>";
}

alert("Saved");
};

var List = function() {
    for (var key in rolodex) {
    var person = JSON.parse(rolodex[key]);
    var div = document.getElementById('list-display');
    div.innerHTML = div.innerHTML + "<div class='sme-entry'><ul class='no-list-style'><li><h3>"+person.subject+"</h3></li><li>"+person.firstname+" "+person.lastname+"</li><li>"+person.email+"</li></ul></div>";
    }
};

var Remove = function() {

};

2 个答案:

答案 0 :(得分:3)

localStorage的关键是进行键值存储。

您给了它一个键("rolodex"),因此它只是一个值JSON.stringify(rolodex);

就持久性而言,你有两种选择: 只要你清楚地了解每个/哪一个是如何运作的,你选择哪个都没关系。

首先,一两个基本规则:

  1. localStorage只是键值,该值必须是字符串(或能够转换为字符串)。

  2. 如果您计划来回存储,从存储到您的应用,那么您需要确保每次都从字符串转换并转换为字符串。

  3. 话虽如此,您的选择如下:

    1. 继续做你正在做的事。现在,您的图表看起来像:
      [{ name : "Bob" }, { name : "Doug" }] // simplified
      所以你知道抓住整个事物的关键点,将它变成一个对象数组并以这种方式处理它是相对简单的。
      好处:就存储方式而言,它很容易使用。
      缺点:如果它变得巨大,它可能开始减速,只有一个键,很容易出错并覆盖所有内容,你必须抓住所有数据来更新一个电子邮件地址,等等...

    2. 为每个人生成一个唯一的ID(可能是它的名字+电子邮件+手机,或完全随机无关紧要)。
      将每个ID推入rolodex
      使用他们的ID单独保存每个联系人 var id = abc123; contact.id = id; rolodex.push(id); localStorage.set(id, JSON.stringify(contact));

    3. 上升空间: 现在,你有自己更安全的物品 编辑和保存时,您只能访问完成工作所需的最低要求 您仍然可以使用rolodex“循环”通过您的联系人(通过id)。

      缺点: 虽然访问一个人的速度更快,但需要才能知道他们的ID 要知道这一点,你可能需要让rolodex打开......很好......但是要知道哪个 ID是对的,你可能需要遍历rolodex,抓住每个ID,一次一个,按ID抓住每个人,然后测试它们,直到找到你想要的那个...... 这样做的效率很多效率低。
      同时,如果您拥有由其他人提供给您的ID,那么抓住合适的人的速度要快得多。索引查找速度非常快,而非索引查找变得非常慢。

      将所有内容构建出来也更复杂 这个例子可能不是很难,但是如果你有不同的ID数组来构建不同类型的对象,那些不同的对象具有属性,这些属性是由ID引用的,然后你将它们链接在一起......

      ...恭喜,您刚刚更换了一个关系数据库,使用数组/属性作为连接外键表,同时将该管理的复杂性从SQL转移到JS(可能更容易或更难,取决于熟练程度)。

      典型应用的理想答案可能在中间:
      保持一组有用的对象循环(例如:first_name + last_name + id + email),同时将这些对象的较大版本保存在自己的密钥下(完整版,带有生日,最新合作伙伴的名字等等,可以让您更快地找到“The Dave's I Know”或“我的家庭成员”列表,而无需打开所有人的帮助。

      当然,那么你需要在两个地方更新用户(虽然合法的名称变更很少,所以你会非常安全,除了通过婚姻来存储多个地点的非易失性数据)。

      完全相同的另一个选项,但在内存加载的另一端,是在应用程序的开头解压所有
      解压缩数组,循环遍历,对于每个ID,将ID替换为该ID的完整对象

      然后,对于该对象的每个属性,如果该属性是一个ID,请抓取该对象的THAT ID,然后附加它,等等......

      现在您已将所有数据保存在内存中,因此您无需再次访问存储,并且您所做的任何更改一次只会发生在一个对象上,因此您只能保存对象(或子目录) - 对象)需要保存。

      当然,这里的缺点是它起步最慢,而且它需要最大的内存(这些日子并不是很重要,除非你希望它能够在几乎不支持localStorage的旧手机上快速运行)

答案 1 :(得分:0)

Localstorage接受你提供的东西。在这种情况下,你给它一个完整的项目数组,这就是它存储在一个键下的内容。您可以单独存储每个项目,但您需要自己跟踪他们的名称(例如,通过在本地存储中存储lastIndexUsed,然后存储"rolodex" + lastIndexUsed的密钥。)

最好是承认你正在存储整个数组,而不是删除它。重新加载数组,并从中删除任何单个项目,然后再次保存数组。