通过HTML表单字段名称获取带有内部对象的JSON对象的值,而不使用eval

时间:2010-11-22 15:05:59

标签: javascript json object eval html-form

我遇到了类似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的好方法。 此解决方案还适用于字段名称中包含任何点数的表单字段。

5 个答案:

答案 0 :(得分:4)

而不是:

eval("sFieldValue = oResponse."+sFieldName); 

用于单点字段:

sFieldValue = oResponse[sFieldName];

这将通过其密钥检索值。

现在,如果您需要更多,则需要执行以下操作:

  1. sFieldName
  2. 上拆分.
  3. 循环遍历该数组并在oResponse中向下,直到达到您想要的值
  4. 代码可能如下所示:

    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

玩得开心

雅舍