javascript - jquery JSON 数组作为 localStorage 项

标签 javascript jquery json local-storage

我的代码几乎没有变化,它部分有效:)

    var db = {
        hotels: JSON.parse(localStorage.getItem('table') || "[]"),

        get objects() {return this.hotels},
        set objects(obj) {
            obj = this.hotels;
            localStorage.setItem('table', JSON.stringify(obj))
        }
    }



jQuery(function(){

    var count = localStorage.getItem('count');
    if(!count) {
     count = 0;
    }


    function Add(item){
        var client = {
            ID    : jQuery(item).find("#txtID").val(),
            Name  : jQuery(item).find("#txtName").val(),
            Photo : jQuery(item).find("#txtPhone").val(),
            Link : jQuery(item).find("#txtEmail").val()
        };
        db.objects = db.objects.push(client);
        count = count+1;
        localStorage.setItem('count',count);

        jQuery('.panel2 a span').text('('+ localStorage.getItem('count') +')');

        jQuery(item).find('.add_rem').hide();
        jQuery(item).find('.remove').show();
        jQuery("#tblList .empty").hide();
        jQuery("#tblList").find('li:gt(0)').remove();

        jQuery.each(db.objects,function(i,element) {
            jQuery("#tblList").append("<li class='added"+db.objects[i].ID+"'>"+
                                         "<img src='../../images/general/delete.gif' alt='Delete"+i+"' class='delete'/>" +
                                         "<a href='"+db.objects[i].Link+"' title='"+db.objects[i].Name+"'>"+
                                         "  <img src='"+db.objects[i].Photo+"' alt='"+db.objects[i].Name+"'>" + 
                                         "  <span>"+db.objects[i].Name+"</span>" + 
                                         "  </a>" + 
                                      "</li>");
        })
        return true;
    }

    function Delete(item){
                jQuery(item).prev('.add_rem').show();
                jQuery(item).find('.remove').hide();
                jQuery(item).find('.remove').removeAttr('alt');

    }

    function List(){
        if(count > 0) {
            jQuery("#tblList .empty").hide();
            jQuery('.panel2 a span').text('('+ localStorage.getItem('count') +')');
        }
        for(var i= 0; i<= count; i++) {
         var cli = JSON.parse(db.hotels);
            if(cli[i] != null){
                jQuery("#"+cli[i].ID).find('.add_rem').hide();
                jQuery("#"+cli[i].ID).find('.remove').show();
                jQuery("#"+cli[i].ID).find('.remove').attr('alt','Delete'+i);
                jQuery("#tblList").append("<li class='added"+cli[i].ID+"'>"+
                                         "<img src='../../images/general/delete.gif' alt='Delete"+i+"' class='delete'/>" +
                                         "<a href='"+cli[i].Link+"' title='"+cli[i].Name+"'>"+
                                         "  <img src='"+cli[i].Photo+"' alt='"+cli[i].Name+"'>" + 
                                         "  <span>"+cli[i].Name+"</span>" + 
                                         "  </a>" + 
                                      "</li>");
            }
        }
    }

    jQuery("#frmCadastre").bind('submit',function(e){   
       e.preventDefault()   
            return Add(this);
    });
        List();

    jQuery(".remove, .delete").bind("click", function(e){
        e.preventDefault();
        Delete(this);
        List();
    });

})

现在我的问题是如何在页面刷新后将元素推送到数组中,这位于 function Add()
数组看起来像这样
"["{"ID":"1","Name":"test","photo":"/link/to/photo.jpg"}"]"

如果我在页面刷新之前添加另一个元素,效果很好
"["{"ID":"0","Name":"test0","photo":"/link/to/photo0.jpg"}","{"ID":"1","Name":"test1","photo":"/link/to/photo1.jpg"}"]"

但是如果我重新加载页面并尝试添加 Firebug 正在抛出的元素:
 `TypeError: db.objects.push is not a function  

 db.objects = db.objects.push(client);`

最佳答案

我们将开始弄清楚 HTML5 本地存储会发生什么。本地存储是由支持它的每个浏览器定义的磁盘中的一个位置。对于每个浏览器,这些位置可能不同。它们保存带有键和值的元组,都是字符串。如果要将整个对象保存到磁盘,则必须对其进行序列化。这意味着您必须将其转换为数据数组,在我们的例子中是 chars -> string。在 javascript 中,最常见的对象序列化函数是 JSON.stringify .它的输入是一个有效的 JSON 对象,在我们的例子中是一个数组,它会使用你用来初始化一个对象的字面量将它变成一个字符串,比如 {x:5} . JSON.stringify([{x:5},{x:6},{x:7}])将有以下输出:"[{x:5},{x:6},{x:7}]" .并从你使用的字符串重建你的对象 JSON.parse(x)在哪里 x 是一个有效的 json 字符串。您现在想要拥有一个对象数组,您首先想到的是将您拥有的数组序列化为 变量 在您的程序中并添加一个您记得将其存储到磁盘中的特殊 key 。每个浏览器都为服务器托管的每个站点提供单独的 localStorage。

在 localstorage 中存储绑定(bind)到键的值的示例如下:

localStorage.setItem('x','5');
localStorage['x'] = 5;
localStorage.x = 5;

他们都做同样的事情,他们的速度是按降序排列的。现在你在 Chrome->resources->localstorage:
+-------------------+
|   Key   |  Value  |
+---------+---------+
|    x    |   "5"   |
+---------+---------+

当您第一次访问该页面时,localStorage 中没有任何内容,因此您必须有一些初始值。试图通过以下方式获得值(value):
return localStorage.getItem('x');
return localStorage['x'];
return localStorage.x;

会给你未定义的。有一个用 javascript 制作的不错的运算符,它是 ||。 .
null || 5          //returns 5
undefined || 3.14  //returns 3.14
'' || 6            //returns 6
[] || {}           //returns []

如果左操作数“存在”,则返回它,否则返回右操作数。 localStorage.getItem('x') || 5 让事情变得更快所以如果一个带有键 的元组x 如果存在,它将返回具有指定键的项目的值,否则它将返回 5,这是我们的初始值。

让我们再次回到 localStorage。请记住,元组被保存到磁盘中,这比 ram 中的访问速度要慢得多。如果我想读取 localStorage 中某个项目的值,让我们循环多次,我应该直接从磁盘读取它,还是应该从磁盘读取一次并将其保存到 ram 中以更快地访问它?你肯定知道什么更有意义......所以我必须有一个变量,它是 localStorage 中的那个的克隆。假设我将其命名为 私有(private)变量 .它必须有一个初始值,它将是:
var private_array = JSON.parse(localStorage.getItem('array')) || [];

当您想更改本地存储中的数组(例如推送项目)时,您可以使用:
private_array.push(item)
localStorage.setItem('array', JSON.stringify(private_array))

您的本地存储将如下所示:
+---------+-----------------------------------------+
|   Key   |                  Value                  |
+---------+-----------------------------------------+
|  array  |  [{"name":"george", "surname":"bush"}]  |
+---------+-----------------------------------------+

为了使代码生成速度更快,而不是程序速度,您可以定义 setter 和 getter。
var obj = {
    temp: 5,
    get x(     ) { return this.temp  },
    set x(value) { this.temp = value }
}

我们有一个名为 obj 的对象、一个成员 temp 以及一个 setter 和一个 getter 函数,就像在一些 java 代码中一样。您可以查看obj.temp === 5 .这些特殊的运算符允许我们写
obj.x = obj.x + 6;

它将像这样执行:
obj.set_x(obj.get_x() + 6);

因此,假设您有一个名为 db 的接口(interface)(数据库,类似于 locastorage 的含义)和一个显然不是的“私有(private)成员”。你可以在 http://ejohn.org/blog/javascript-getters-and-setters/ 看到一个实现。与 __define(G/S)etter__ 它有真正的私有(private)成员,但这个肯定写得更快,更易读。
var db = {
    cl_arr: JSON.parse(localStorage.getItem('array')) || [],
    get clients( ) { return this.cl_arr },
    set clients(v) { 
        localStorage.setItem('array', JSON.stringify(this.cl_arr));
        if(v.constructor === Array) { this.cl_arr = v }
    }
}

所以当我执行时:
db.clients.filter(function(client) { return client.money > 1000 });

这将被执行
db.get_clients().filter...;

当我尝试更改数组时,我会写这个
db.clients = db.clients.push(client);

即使push方法可以改变数组,也只有获取 函数将被触发,因此只有“私有(private)” cl_arr 变量会改变,以触发 二传手这也更新了我们的 localStorage 我必须写 db.clients = ...

关于javascript - jquery JSON 数组作为 localStorage 项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20183203/

相关文章:

javascript - JQuery 插件类不工作

jquery - ajax 和 jquery 有什么区别,哪个更好?

javascript - 如何在悬停时滑出内容 - flexbox-layout

c# - 反序列化未知维度的锯齿状数组

javascript - 我正在尝试使用 AngularJS 发布数据

javascript - 带有 *ngIf 的 Angular 2 条件循环

javascript - AngularJS - 在不删除验证错误的情况下设置原始表单

javascript - jQuery 可拖动 div 周围的区域变暗?

javascript - 制作一个从 Youtube 获取信息的 JavaScript 脚本

php - 将 mySQL 查询显示为 JSON 对象