【问题标题】:Deserializing JSON from local storage to Fabric JS object - JSON created from form data将 JSON 从本地存储反序列化为 Fabric JS 对象 - 从表单数据创建的 JSON
【发布时间】:2014-01-23 01:16:53
【问题描述】:

我正在将 Fabric js 用于我正在从事的项目并遇到一些困难。我的目标是允许用户在表单中输入详细信息。然后表单将转换为 JSON 对象并使用本地存储进行存储。

按下提交后,用户将被带到一个新页面,在该页面中检索 JSON 并创建对象。

我在后面的部分有困难。将表单中的信息转换为 JSON 工作正常,各种测试表明输出是应有的。

创建对象时出现问题,对象在画布上显示为带角的简单边框,可以移动和选择它,但所有其他属性(例如大小和颜色)都丢失了。我认为这是因为 JSON 是如何被反序列化的。我一直在寻找解决方案,但尚未找到,非常感谢任何帮助。

示例代码:

这是我的测试实例,它按预期创建了一个对象:

var a = {
    type: "rect",
    left:200,
    top:110,
    fill:'red',
    width:80,
    height:50
};

同上,但来自本地存储:

[Log] From JSON:    {"type":"rect","top":"110","left":"200","fill":"red","height":"50","width":"80"} (sim.html, line 135)

要获取我正在使用的数据:

var test = localStorage.getItem("Number1");
console.log("From JSON: " +test);

var obj = JSON && JSON.parse(test) || $.parseJSON(test);
console.log(obj.type +"-"+ obj.left);

在下面的方法中添加 a 时,它可以工作,但 obj 不能。我可以看到报价的主要区别,但我不确定这是否是问题,如果是,如何简单地删除它。

迭代和渲染对象的函数:

    fabric.util.enlivenObjects([circle1, obj], function(objects) {
    var origRenderOnAddRemove = canvas.renderOnAddRemove;
    canvas.renderOnAddRemove = false;

    objects.forEach(function(o) {
        canvas.add(o);
    });
    canvas.renderOnAddRemove = origRenderOnAddRemove;
    canvas.renderAll();
});

非常感谢您的帮助。

【问题讨论】:

  • 您的 JSON 对我来说看起来不正确 - 数字都是字符串。如何将对象放入存储?
  • 你应该使用JSON.stringify( object )edit 嗯好的 - 您保存的对象与“a”对象相同,因为您将表单字段保存为字符串而不是数字。我不知道这是否是问题的原因。
  • 是的,抱歉我更新了那条评论。
  • 好吧,表单字段值总是字符串,所以在某些时候代码必须知道哪些需要转换为数字。 (再次,假设数字/字符串确实是问题所在。)这种转换可能在您序列化表单时发生,也可能稍后发生。
  • 也许您可以修改序列化程序代码,以便它可以在输入元素上查找“数字”类,并在此时转换它们。

标签: javascript json local-storage deserialization fabricjs


【解决方案1】:

我认为您可以修改“序列化”例程,以便将适当的输入转换为数字:

$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        var value = this.value || '';
        if (/^\d+$/.test(value))
          value = +value;

        if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(value);
        } else {
            o[this.name] = value;
       }
    }} );
    return o;
};

这会查找看起来像数字的输入值并将它们转换。 (它只查找整数;如果您还想测试带小数的数字,可以修改正则表达式。)

这不是世界上最可靠的东西,因为它做了一个相当大的假设。为了更准确,您必须使用类标记表单输入,以确定它们是否应该被视为数字,然后实现您自己的序列化程序来遍历所有输入。

【讨论】:

  • 太棒了!谢谢尖头!你能说为什么当我尝试 if(name == "bla"){do bla} 它还没有工作吗?它是否以不同的方式评估字符串?
  • @SteveGreen 好吧,不,我不完全确定,但如果您有一些非数字字段,那么显然您不想将它们转换为数字;你最终会得到NaN。我倾向于使用+Number 构造函数进行转换,因为parseInt 会忽略字符串末尾的垃圾(尽管有时这可能是理想的行为)。
  • 我也觉得这有点奇怪,但归结为对 JS 的了解不够,无法正确理解它。我能够返回字段名称,然后比较它们,但仍然没有。但是,您的解决方案可以完美运行,而不是您的时间和帮助。现在进入下一个任务 - 从表单中创建一个树,这只是一个条目,我现在需要多个:D
猜你喜欢
  • 2019-04-05
  • 1970-01-01
  • 2019-11-20
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
相关资源
最近更新 更多