【问题标题】:How to retrieve the data from localstorage in the order we set it如何按照我们设置的顺序从本地存储中检索数据
【发布时间】:2014-01-15 01:46:20
【问题描述】:

我正在通过循环访问顶部菜单(对象数组)来读取一个 json 文件,然后将其取出并将其存储到本地存储中。一切正常,甚至数据都存储在本地存储中。但我的问题是它以排序顺序将数据存储在 localStorage 中,这可能是它的默认行为。但我不需要它按排序顺序,我希望它按照它在 json 中出现的顺序。因为当我将数据存储到 localstorage 并从 localstorage 读取数据时,它是按排序顺序排列的。如果它自动排序,我可以使用 $.each 中的键并附加它来维护我们的顺序。但为什么它会自行排序。有没有其他的解决方法。请帮我解决这个问题。

注意:
我需要将数据从 json 存储到 localStorage。然后从 localstorage 中读取它,并且在 localstorage 完全为空之前不要读取 json。当我手动更改本地存储中的值时,它应该反映在菜单中。我已经完成了所有条件编码,只需要弄清楚本地存储问题,即按排序顺序存储它。

以下是我的 JSON 文件、javascript 和部分 html:

JSON

{
    "topmenu":
    [
        {
            "item": "File"
        },
        {
            "item": "Help"
        },
        {
            "item": "Edit"
        },
        {
            "item": "View"
        },
        {
            "item": "Go"
        },
        {
            "item": "Tools"
        },
        {
            "item": "Actions"
        }
    ]
}

JAVASCRIPT

<script>
$(function() {
    if (typeof localStorage === "undefined") {
        alert("Sorry, your browser does not support web storage...");
    }

    $.getJSON("header.json", function(data) {        
        $.each(data.topmenu, function(key, val) {
            localStorage.setItem(val.item, val.item);
        });
        loadMenu();
    });

    function loadMenu() {
        $('.horizontalmenu').html('');
        if (!localStorage.length < 1) {
            for (var i = 0; i < localStorage.length; i++) {
                var item = localStorage.getItem(localStorage.key(i));
                $('.horizontalmenu').append('<li class="menu"><a href="#">' + item + '</a></li>');
            }
        } else {
            $('.horizontalmenu').html("<li class='menu'>No menu</li>");
        }
    }
});
</script>

部分 HTML

<div id="header">
        <div id="header-title">
        Test
        </div>
        <div id="header-menu">
                <ul class="horizontalmenu">
                </ul>
        </div>
</div>

【问题讨论】:

  • 您是否尝试连接索引 + 您的密钥?例如:1_文件; 2_帮助。或者在你的json“位置”中创建另一个属性并使用underscore.js按顺序检索。

标签: jquery json html local-storage


【解决方案1】:

存储 JSON 本身。 localStorage 就像一个没有顺序的对象。

localStorage.setItem("menu_items", JSON.stringify(data));

然后你可以得到 JSON 并使用 JSON.parse() 方法解析它。

但是,我不确定您为什么要存储这些项目,为什么不将数据传递给您的 loadMenu 函数?

loadMenu(data.topmenu);

function loadMenu(elems) {
    // var elems = JSON.parse(localStorage.getItem("menu_items")).topmenu;
    $('.horizontalmenu').empty();
    if (elems.length) {
        for (var i = 0; i < elems.length; i++) {
            var item = elems[i].item;
            $('.horizontalmenu').append('<li class="menu"><a href="#">' + item + '</a></li>');
        }
    } else {
        $('.horizontalmenu').html("<li class='menu'>No menu</li>");
    }
}

【讨论】:

  • 其实需求是这样的。我们需要将数据从 json 存储到 localStorage。然后从 localstorage 中读取它,并且在 localstorage 完全为空之前不要读取 json。当我们在本地存储中手动更改值时,它应该反映在菜单中。我已经完成了所有条件编码,只需要找出本地存储问题。自行排序
  • @susheel 正如我在答案中提到的,localStorage 项目不保留顺序(就像对象的属性),您应该存储类似数组这个项目。这就是为什么我建议存储 JSON,因为它包含有序集合(即数组)。
  • 但我没有在您的代码中看到从 localStorage 中检索的内容??您的代码直接读取 json 并显示将其添加到菜单中
  • @susheel 其实有,你看到评论的那行了吗?
  • 你评论了所以我忽略了它。让我试试
【解决方案2】:

终于从用户@BlackSheep的回答中得到了一个想法,并基于它发布了我的解决方案。让我解释一下代码的行为:

我的代码实际上检查了 localstorage 是否为空,或者如果它不为空,那么它会检查它的值(localStorage 值,它是 json 字符串)是否等于实际的 json(转换为字符串)。进行此检查是为了确保,如果将新项目添加到 json 文件中,它甚至应该在本地存储中更新它。如果这两个条件都失败了,它什么也不做,并继续从 localStorage 中读取。

在加载菜单中,我只是从本地存储中读取 json 字符串的值,因此将其转换为 json 对象并解析它以获取值。看起来很复杂,但这是要求。我可以通过解析json并在菜单中显示来直接完成。

<script>
$(function() {
    if (typeof localStorage === "undefined") {
        alert("Sorry, your browser does not support web storage...");
    }

    $.getJSON("data/header.json", function(data) {
        if ((localStorage.length === 0) || (localStorage.getItem("menu_items") != JSON.stringify(data))) {
            localStorage.setItem("menu_items", JSON.stringify(data));
        }
        loadMenu();
    });

    function loadMenu() {
        $('.horizontalmenu').empty();
        if (!localStorage.length < 1) {            
                var item = JSON.parse(localStorage.getItem("menu_items"));
                $.each(item.topmenu,function(key,val){
                     $('.horizontalmenu').append('<li class="menu"><a href="#">' + val.item + '</a></li>');
                });               
        } else {
             $('.horizontalmenu').html("<li class='menu'>No menu</li>");
        }
    }
});
</script>

【讨论】:

    【解决方案3】:

    您为什么同时使用 val.item 作为键和值? 数字索引作为键怎么样?然后在 for 循环中按索引检索。

    【讨论】:

    • 我已经做到了,它已经可以工作了。但是为什么本地存储排序本身是我的问题(可能是内置功能)。只是想知道是否有办法让我们按照我们需要的顺序存储它,名称而不是数字。只是为了清楚具体项目实际上是什么:我什至可以做 1_file 等,但这没有意义,看起来像脏修复。
    • 我在规范中没有看到任何关于本地存储中项目保证顺序的内容。因此这是不可预料的,这就是为什么检查索引或时间戳似乎是必要的。
    • 感谢您的回复,我有另一个解决方案,我已经回答了。你可以看看那个:)
    • 顺便说一下,本地存储是按字母顺序排序的,至少在 chrome 中是这样。
    • 是的,它在 chrome 中可以。
    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    • 2016-04-02
    相关资源
    最近更新 更多