例如。我们有这样的形式:
<form id="to-object">
<input name="data[zero_key]" value="It`s too simple" />
<input name="data[first_key][value]" value="It`s simple too" />
<input name="data[second_key][]" value="Push me" />
<input name="data[second_key][]" value="Push me please" />
<input name="data[next_key][0][type]" value="I don`t wanna be object with key 0. " />
<input name="data[next_key][0][number]" value="I`m array!!!" />
</form>
所以问题是:如何正确序列化这个表单并得到这个结果:
{
"zero_key": "It`s too simple",
"first_key": {
"value": "It`s simple too"
},
"second_key": [
"Push me",
"Push me please",
],
"next_key": [
{
"type": "I don`t wanna be object with key 0.",
"number": "I`m array!!!"
},
],
}
我有什么:
(function($) {
$.fn.convertFormDataToObject = function(){
var extractFieldNames = function(fieldName, expression, keepFirstElement)
{
expression = expression || /([^\]\[]+)/g;
keepFirstElement = keepFirstElement || false;
var elements = [];
while((searchResult = expression.exec(fieldName)))
{
elements.push(searchResult[0]);
}
if (!keepFirstElement && elements.length > 0) elements.shift();
return elements;
}
var attachProperties = function(target, properties, value)
{
var currentTarget = target;
var propertiesNum = properties.length;
var lastIndex = propertiesNum - 1;
for (var i = 0; i < propertiesNum; ++i)
{
currentProperty = properties[i];
if(currentProperty == ""){
var intKey = Math.floor(Math.random() * (99 - 1)) + 1;
currentProperty = intKey.toString();
} else if(!isNaN(currentProperty)) {
currentProperty = [parseInt(currentProperty)];
} else {
currentProperty = properties[i];
}
if (currentTarget[currentProperty] === undefined)
{
currentTarget[currentProperty] = (i === lastIndex) ? value : {}; }
currentTarget = currentTarget[currentProperty];
}
}
var convertFormDataToObject = function(form) {
var currentField = null;
var currentProperties = null;
// result of this function
var data = {};
// get array of fields that exist in this form
var fields = form.serializeArray();
for (var i = 0; i < fields.length; ++i)
{ currentField = fields[i];
// extract field names
currentProperties = extractFieldNames(currentField.name);
// add new fields to our data object
attachProperties(data, currentProperties, currentField.value);
}
return data;
}
var form = $(this);
var data = convertFormDataToObject(form);
return data;
};
})(jQuery);
正如您在本示例中所见,我使用随机int生成器来解决[]
之间空白空间的问题。这是一个问题,但并不重要。至关重要的是,我无法修复阵列生成问题。此脚本将name属性中的所有键添加为对象的键,并提供错误的对象。它不是带有对象的数组,而是为对象提供键&#34; 0&#34;,&#34; 1&#34;例如"0":{},"1":{}
而不是[{},{}]
。
如果您知道如何使用JS修复它,我将非常感谢您的帮助!
答案 0 :(得分:1)
你可以大大减少代码的复杂性,尝试这样的事情:
const finalObj = [...document.querySelector('form').children].reduce((objSoFar, child) => {
const value = child.value;
let allKeys = child.name.slice(4).split('][');
allKeys[0] = allKeys[0].slice(1);
const lastKeyIndex = allKeys.length - 1;
allKeys[lastKeyIndex] = allKeys[lastKeyIndex].slice(0, allKeys[lastKeyIndex].length - 1);
// now: eg "data[next_key][0][number]" has allKeys ["next_key", "0", "number"]
let refObj = objSoFar;
while (allKeys.length > 1){
if (!refObj[allKeys[0]]) {
if (allKeys[1] === '' || /^\d+$/.test(allKeys[1])) refObj[allKeys[0]] = [];
else refObj[allKeys[0]] = {};
}
refObj = refObj[allKeys[0]];
allKeys = allKeys.slice(1);
}
const lastKey = allKeys[0];
if (lastKey === '') refObj.push(value);
else refObj[lastKey] = value;
return objSoFar;
}, {});
console.log(finalObj);
const desiredSerializedResult = '{"zero_key":"It`s too simple","first_key":{"value":"It`s simple too"},"second_key":["Push me","Push me please"],"next_key":[{"type":"I don`t wanna be object with key 0.","number":"I`m array!!!"}]}';
if (JSON.stringify(finalObj) === desiredSerializedResult) console.log('Matches desiredSerializedResult');
<form id="to-object">
<input name="data[zero_key]" value="It`s too simple" />
<input name="data[first_key][value]" value="It`s simple too" />
<input name="data[second_key][]" value="Push me" />
<input name="data[second_key][]" value="Push me please" />
<input name="data[next_key][0][type]" value="I don`t wanna be object with key 0." />
<input name="data[next_key][0][number]" value="I`m array!!!" />
</form>
(但这看起来似乎是一个XY问题 - 几乎可以肯定,设置应用程序的方式比需要这样的逻辑的方法更好)