JavaScript中如何用serializeObject序列化表单得到嵌套二维数组结构
解决方案
你遇到的问题核心有两点:
- 输入框的
name属性没有携带resource_ratio父字段标识,所以序列化后数组直接挂载到了根层级 - 你使用的
serializeObject插件仅支持单层name分组,无法解析带方括号的嵌套数组命名格式
你可以根据需求选择以下两种修改方案:
方案1:改动最小的手动组装方案
不需要修改序列化插件和渲染逻辑,序列化完成后手动拼接成目标结构即可:
// 保留你当前的渲染代码不变,序列化后得到{0:[...],1:[...]}结构 var dataBox = $('#inputDataForm').serializeObject(); // 手动组装为目标结构 var result = { resource_ratio: [ dataBox['0'], dataBox['1'].map(Number) // 将第二组字符串类型的数值转回数字类型,匹配原始结构 ] }; // 后续直接使用result即可
方案2:升级序列化插件支持嵌套结构
适合需要通用支持多层嵌套表单的场景,需要同时修改渲染逻辑和序列化插件:
第一步:调整渲染代码的输入框命名
给输入框的name属性加上父字段标识和层级索引:
for (var i = 0; i < selectedData.resource_ratio.length; i++) { resourceRatioBoxTag[i] = "<p id='resourceRatio[" + i + "]'>"; for (var j = 0; j < selectedData.resource_ratio[i].length; j++) { // 核心修改:name格式为resource_ratio[层级索引] resourceRatioBoxTag[i] += `<input type="text" id="resourceRatio[${i}][${j}]" value="${selectedData.resource_ratio[i][j]}" name="resource_ratio[${i}]">`; } resourceRatioBoxTag[i] += "</p>"; $("#resourceRatioDiv").append(resourceRatioBoxTag[i]); }
第二步:替换升级serializeObject插件
新版本支持自动解析嵌套格式的name,生成对应层级结构:
$.fn.serializeObject = function () { var o = {}; var a = this.serializeArray(); var regName = /([^\[\]]+)(\[\])?/g; $.each(a, function () { var name = this.name; var value = this.value || ''; var match; var current = o; var parts = []; while ((match = regName.exec(name)) !== null) parts.push(match[1]); regName.lastIndex = 0; for (var k = 0; k < parts.length; k++) { var key = parts[k]; var isLast = k === parts.length - 1; if (isLast) { current[key] = current[key] ? (Array.isArray(current[key]) ? current[key] : [current[key]]).concat(value) : value; } else { current[key] = current[key] || (isNaN(parts[k+1]) ? {} : []); current = current[key]; } } }); // 自动转换第二组数值为数字类型,可根据需求删除 if (o.resource_ratio?.[1]) o.resource_ratio[1] = o.resource_ratio[1].map(Number); return o; };
修改后直接调用$('#inputDataForm').serializeObject()即可得到符合要求的结构。
内容的提问来源于stack exchange,提问作者user16535642
相关产品推荐
相关产品推荐

