如何使用jQuery将查询字符串或JSON对象映射转换为单个JSON对象?

3
假设我有一个表单,其中包含一系列月份和相应的复选框。我需要帮助解决以下两个问题之一:
1. 将查询字符串(例如 "January=on&March=on&September=on")转换为一个 JSON 对象。 2. 将对象数组(如:[{ January: 'on' },{ March: 'on' },{ September: 'on' }])转换为单个 JSON 对象:{ January: 'on', March: 'on', September: 'on' }。
我知道第一个映射已经是 JSON 了,但我希望它不要是对象数组,而是单个 JSON 对象。我可以使用 $('form').serializeArray() 方法构建映射,也可以使用 $('form').serialize() 方法构建查询字符串。
jQuery API 中 .serialize() 的实现代码如下:
serialize: function() {
    return jQuery.param(this.serializeArray());
},

这就是为什么我可以处理第一个或第二个答案。

我想这样做的原因是因为我正在从PrototypeJS转换到jQuery,而在PrototypeJS中,这很简单:

Object.toJSON(Form.serializeElements($('myform'), true));

那么,有没有人知道一个JSON插件(我想只使用jQuery)可以轻松地实现这个目标,或者知道一个简单的方法来达到我要寻找的结果?谢谢!

5个回答

10

你可以尝试这个

String.prototype.QueryStringToJSON = function () {
href = this;
qStr = href.replace(/(.*?\?)/, '');
qArr = qStr.split('&');
stack = {};
for (var i in qArr) {
    var a = qArr[i].split('=');
    var name = a[0],
        value = isNaN(a[1]) ? a[1] : parseFloat(a[1]);
    if (name.match(/(.*?)\[(.*?)]/)) {
        name = RegExp.$1;
        name2 = RegExp.$2;
        //alert(RegExp.$2)
        if (name2) {
            if (!(name in stack)) {
                stack[name] = {};
            }
            stack[name][name2] = value;
        } else {
            if (!(name in stack)) {
                stack[name] = [];
            }
            stack[name].push(value);
        }
    } else {
        stack[name] = value;
    }
}
return stack;
}

查询字符串

    href="j.html?name=nayan&age=29&salary=20000&interest[]=php&interest[]=jquery&interest[1]=python&interest[2]=Csharp&fan[friend]=rangan&fan[family]=sujan&sports[1]=cricket&sports[2]=football";

使用方法

alert(href.QueryStringToJSON().toSource())

输出结果

({name:"nayan", age:29, salary:20000, interest:["php", "python", "Csharp"], fan:{friend:"rangan", family:"sujan"}, sports:{1:"cricket", 2:"football"}})

4

kgiannakakis提出的遍历地图的建议是一个很好的起点,但我觉得它并不符合我的原问题的答案。经过几个小时的头痛,我选择了这个方法,它允许您根据自定义属性序列化元素(我不想使用jQuery要求的“name”属性来命名我的表单元素)。我还开始使用来自json.org的JSON库来将我创建的对象字符串化。我的插件的serializeToJSON函数就是我寻找的答案,其余部分只是额外的。

注意:这是为客户端而做的,因此“CustomXXX”名称和属性被替换为它们实际的名称和属性。

jQuery.fn.extend({
    serializeCustomPropertyArray: function() {
        return this.map(function() {
            return this.elements ? jQuery.makeArray(this.elements) : this;
        }).filter(function() {
            return jQuery(this).attr('CustomAttribute') &&
                (this.checked || /select|textarea/i.test(this.nodeName) ||
                        /text|hidden|password|search/i.test(this.type));
        }).map(function(i, elem) {
            var val = jQuery(this).val();
            return val == null ? null : jQuery.isArray(val) ?
                jQuery.map(val, function(val, i) {
                    return { name: jQuery(elem).attr('CustomAttribute'), value: val };
                }) : { name: jQuery(elem).attr('CustomAttribute'), value: val };
        }).get();
    },
    serializeToJSON: function() {
        var objectMap = this.serializeCustomPropertyArray();
        var objectJson = new Object;
        jQuery.each(objectMap, function() {
            objectJson[this.name] = (this.value !== null) ? this.value : 'null';
        });
        return JSON.stringify(objectJson);
    }
});

这可以这样调用:

$('#fields').find(':input[CustomGroup="Months"]').serializeToJSON();

假设您的文档类似于以下内容:
<div id="fields">
   <input type="checkbox" CustomGroup="Months" CustomAttribute="January" />January<br />
   <input type="checkbox" CustomGroup="Months" CustomAttribute="February" />February<br />
   ...
</div>

构建的JSON看起来像这样:
{ January: 'on', February: 'on', ... }

0
你可以使用 $.each 实用函数遍历对象映射。
$(function() {
    map = [{ January: 'on' },{ March: 'on' },{ September: 'on' }];
    $.each(map, function() {
       $.each(this, function(key, val) {alert(key + " = " + val);});;
    });
});

第一个 each 获取所有数组对象。使用第二个 each 可以获取对象的键和值。


我认为这是一个不错的开始——至少有些东西可以让我去处理。如果地图中的每个对象都可以有相同的名称,那该怎么办呢?虽然这不是必需的,但如果未来出现这种情况,我想要处理它。这会使复杂度大大增加。不过,我会以你的例子为基础开始着手处理。 - Cᴏʀʏ

0

我知道你正在尝试将查询字符串转换为JSON对象,但也许你会对直接从HTML表单转换为JSON对象感兴趣(而不必指定非常复杂的名称属性)。如果是这样,请查看JSONForms: http://code.google.com/p/jsonf/

免责声明:我启动了jsonforms项目。它还很年轻,但我个人认为它非常棒!


很酷,但并没有解决问题。我正在使用ASP.NET,所以由于到处都有NamingContainers所做的名称混淆,你的库不会创建非常友好的对象属性名称。 - Cᴏʀʏ

0
你也可以使用 parseQuery插件 从序列化的元素中创建一个对象。
var contact = $.parseQuery($("#step1 *").serialize());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接