【问题标题】:Convert a JSON object to nested form fields?将 JSON 对象转换为嵌套表单字段?
【发布时间】:2009-05-01 21:22:39
【问题描述】:

任何人都知道将 JSON 对象转换为嵌套表单字段的好方法。

例如:考虑一个 JSON 对象:

{'a':{'b':{'c':'1200'}}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}}

我应该得到:

{'a[b][c]':'1200', 'z':'foo', 'bar[baz]':'1', 'bar[id]':2};

有什么想法吗?

我目前正在使用 jquery,感觉像这样的东西已经存在,如果没有,我可以简单地用一个疯狂的算法自己动手,但我宁愿使用有可靠记录的东西。

【问题讨论】:

  • 什么是嵌套表单域?这些是字段集元素吗?我不太明白你甚至暗示从第一个对象到第二个对象的算法。
  • 嗯,这到底是什么?您可能需要提供一些说明,因为如果没有更多上下文,这并没有多大意义......
  • 您已经可以将元素称为 obj['a']['b'['c'] 是否会改变您的表单字段遍历算法更好一点?
  • 我也有同样的问题,我正在使用 FormData 传递一些文件附件,但是如果我有一个大的嵌套表单,使用 form.append 方法非常乏味。

标签: javascript jquery json


【解决方案1】:

所以,我不知道你为什么要做你说你想做的事,我希望你能把我们都填满,但是这段代码应该足够接近你可以调整它(这是基于some code of mine that I use to find differences in JavaScript object graphs):

function doStrangeThing(obj) {
   var propertyChanges = [];
    var objectGraphPath = [];
    (function(obj, refObj) {
        if ( obj.constructor == Object || (obj.constructor != Number &&
             obj.constructor != String && obj.constructor != Date && obj.constructor != Boolean &&
             obj.constructor != RegExp && obj.constructor != Function)) {
            for (var property in obj) {
                objectGraphPath.push((objectGraphPath.length > 0) ? "[" + property + "]" : property);
                if (obj[property].constructor != Function) {
                    if (!refObj[property]) refObj[property] = {};
                    arguments.callee(obj[property], refObj[property]);
                }
                objectGraphPath.pop();
            }
        } else if (obj.constructor != Function) {
            if (obj != refObj) {
                propertyChanges.push("\"" + objectGraphPath.join("") + "\":\"" + obj.toString() + "\"");
            }
        }
    })(obj, {});
    return "{" + propertyChanges.join(",") + "}";
}

这是我为测试它所做的:

doStrangeThing({'a':{'b':{'c':'1200'}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}});

这会产生这个值:

{"a[b][c]":"1200","z":"foo","bar[baz]":"1","bar[id]":"2"}

希望在某种程度上对你有用...

【讨论】:

  • 一旦到达服务器端,在 php 中它就变成了嵌套的哈希映射。
  • 好吧,如果它对你有用,请将其标记为答案 - 我对 PHP 或对此的需求一无所知,但显然你有你的理由。 :) 再一次,它可能需要稍微调整一下,让它完全按照你的意愿做事,但这对我来说测试和玩起来相对较快,因为我很久以前就写过这段代码了......
  • 顺便说一下,当我说“tweak”时,我的意思是让值类型正常工作 - 我看到您希望“bar[id]”的值是文字数字 2,不是字符串(“2”) - 您可以调整代码以测试是否有数字,如果是,不要使用引号;等
  • Jason Bunting:+1 免费。我知道这有多讽刺。 :)
  • @JasonBunting 如果你像我一样坚持使用 FormData,这非常重要:)。
【解决方案2】:
obj = {'a':{'b':{'c':'1200'}}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}}

内部等价于

{['a']['b']['c']:'1200', ['z']:'foo', ['bar']['baz']:'1', ['bar']['id']:2}

请注意,这不再是 JSON 对象了。

您已经可以通过这种方式引用第一个对象属性:

var z = obj['a']['b']['c']   // 1200

是否足以满足您的需求?您真的要将属性名称转换为变量吗?

【讨论】:

  • 当我读到这个答案时,我不得不笑,因为我想我在读到这个问题时也有同样的感觉 - 即 WTF 这家伙会处理这个烂摊子吗?!尽管如此,这是一个有趣的练习,但我不知道“未知”在 PHP 中对这些东西做了什么。奇怪的东西。
  • 其实我得到了他想要的。很奇怪,但也有点意思。然而,有很多更简单的算法方法可以实现相同的目标......如果变量名和命名空间应该被实现为常见用途,那么它将会非常混乱。
【解决方案3】:

我实际上会推荐一个函数,它接受一个嵌套的 JSON 对象并将其转换为一个 HTTP POST 字符串。 jQuery 将接受它的所有需要​​ HTTP 参数的参数。

我已经在几个生产应用程序中编写并使用了以下功能(使用风险自负):

$.httpSerialize = function(items, parentName) {
    var serializedItems = [], serialize = arguments.callee, encodeItem =     function(key, value) {
        if (value === null || typeof value == 'undefined') return value;
        if (value.constructor == Array) {return serialize(value, key);}
        return (value.constructor == Object)
            ? serialize(value, key)
            : (value === true || value === false)
                ? key+"="+new Number(value)
                : key+"="+encodeURIComponent(value);
    };

    if (items.constructor == Array) {
        parentName = parentName || 'item';
        for (var i = 0; i < items.length; i++) {
            var key = parentName+'['+i+']', value = items[i];
            serializedItems.push(encodeItem(key, value));
        }
    } else {
        parentName = parentName || '';
        for (var key in items) {
            var value = items[key];
            if (parentName) {
                serializedItems.push(encodeItem(parentName+'['+encodeURIComponent(key)+']', value));
            } else {
                serializedItems.push(encodeItem(encodeURIComponent(key), value));
            }
        }
    }
    return serializedItems.join("&");
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 2023-01-16
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    相关资源
    最近更新 更多