我遇到了类似Convert an HTML form field to a JSON object with inner objects的问题,但问到了另一个方向。
这是来自服务器的JSON对象响应:
{
company : "ACME, INC.",
contact : {
firstname : "Daffy",
lastname : "Duck"
}
}
这是HTML表单:
<form id="myform">
Company: <input type="text" name="company" />
First Name: <input type="text" name="contact.firstname" />
Last Name: <input type="text" name="contact.lastname" />
</form>
这是(伪)代码:
var aFormFields;
for (var i = 0, iMax = aFormFields.length; i < iMax; i++) {
var sFieldName = aFormFields[i].getAttribute('name');
eval("sFieldValue = oResponse."+sFieldName);
}
好的我的解决方案有效,但我正在寻找一种从代码中删除邪恶eval的好方法。 此解决方案还适用于字段名称中包含任何点数的表单字段。
答案 0 :(得分:4)
而不是:
eval("sFieldValue = oResponse."+sFieldName);
用于单点字段:
sFieldValue = oResponse[sFieldName];
这将通过其密钥检索值。
现在,如果您需要更多,则需要执行以下操作:
sFieldName
.
oResponse
中向下,直到达到您想要的值代码可能如下所示:
var node = oResponse, parts = sFieldName.split('.');
while(parts.length > 0) {
node = node[parts.shift()];
}
// node will now have the desired value
有关“会员经营者”的进一步资料:
https://developer.mozilla.org/en/JavaScript/Reference/Operators/Member_Operators
答案 1 :(得分:2)
这适用于单个属性:
sFieldValue = oResponse[sFieldName]
但它不适用于contact.firstname等嵌套数据。 为此,用点分割名称,并使用循环遍历每个名称:
var aFormFields;
for (var i = 0, iMax = aFormFields.length; i < iMax; i++) {
var aFieldNameParts = aFormFields[i].getAttribute('name').split(".");
var oFieldValue = oResponse;
for(var j=0; j<aFieldNameParts.length; j++) {
oFieldValue = oFieldValue[aFieldNameParts[j]];
}
var sFieldValue = oFieldValue;
}
注意:如果属性不存在,则会发生错误。您可能想要检查oFieldValue[ aFieldNameParts[j] ]
是否存在。
答案 2 :(得分:0)
虽然有可能,但我不会遍历输入字段,而是遍历JSON对象:
function fillForm (form, data, prefix) {
prefix = prefix ? prefix + "." : "";
for (var x in data) {
if (typeof data[x] === "string") {
var input = form.elements[prefix + x];
if (input)
input.value = data[x];
} else
fillForm(form, data[x], prefix + x);
}
}
fillForm(document.getElementById("myform"), oResponse);
(未测试的)
答案 3 :(得分:0)
假设您的命名方案一致,您可以将点符号转换为下标。您必须在句点上拆分字段名称并迭代或递归标记,将每个转换为下标。当然,这假设oResponse
总是包含每个字段的值。
for (var i = 0; i < aFormFields.length; i++) {
var sFieldName = aFormFields[i].getAttribute('name');
var tokens = sFieldName.split('.');
var cur = oResponse;
for (var j = 0; j < tokens.length; j++) {
cur = cur[tokens[j]];
}
sFieldValue = cur;
}
答案 4 :(得分:0)
请将此视为答案和问题的组合:)
我正在尝试让我的服务器jsonify我从表单发送的数据就像你一样...
在我的情况下,表单最终会创建一个带有多个子对象的json对象,这些子对象可以有子对象,也可以有......。
深度取决于用户,因此我应该能够支持无限递归。
我的解决方案&#34;到目前为止只是感觉不对,但它正确地完成了工作, 函数getRequestBody从expressjs获取req.body对象, 这基本上是一个具有以下映射的对象:
{
"ridic-ulously-deep-subobject": "value",
"ridic-ulously-deep-subobject2": "value",
"ridic-ulously-deep2-subobject3": "value",
}
以下html正在使用中:
<form>
<input name="ridic-ulously-long-class-string" value="my value" />
</form>
和javascript函数(应该通用工作,如上所述为它提供一个req.body对象,它将返回一个json对象):
function getRequestBody(reqB){
var reqBody = {};
for(var keys in reqB) {
var keyArr = keys.split('-');
switch(keyArr.length){
case 1:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
reqBody[keyArr[0]] = reqB[keys];
break;
case 2:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
if(!reqBody[keyArr[0]][keyArr[1]]) reqBody[keyArr[0]][keyArr[1]] = {};
reqBody[keyArr[0]][keyArr[1]] = reqB[keys];
break;
case 3:
if(!reqBody[keyArr[0]]) reqBody[keyArr[0]] = {};
if(!reqBody[keyArr[0]][keyArr[1]]) reqBody[keyArr[0]][keyArr[1]] = {};
if(!reqBody[keyArr[0]][keyArr[1]][keyArr[2]]) reqBody[keyArr[0]][keyArr[1]][keyArr[2]] = {};
reqBody[keyArr[0]][keyArr[1]][keyArr[2]] = reqB[keys];
break;
case 4:
// ...
//and so on, always one line longer
}
return reqBody;
}
这只是感觉不对,它现在只覆盖5个子对象, 可能会发生一个应用程序有足够的功能来达到七个甚至十个级别。
这个应该是一个常见的问题,但我的搜索工作在10分钟内没有发现, 这通常意味着我错过了一些关键字 要么 虽然没有可行的解决方案(在这种情况下我无法想象)。
是否有人有足够的想象力和足够的逻辑来解释这一点,或者我是否只需要更加混乱地扩展这个功能以使我达到10个可能的子级别?
我认为最终它不会在性能方面产生很大的影响, 但我真的不想创造这个可怕的庞然大物:D
玩得开心
雅舍