【问题标题】:Append nested JSON object key to loop - Convert JSON to input field values dynamically将嵌套的 JSON 对象键附加到循环 - 将 JSON 动态转换为输入字段值
【发布时间】:2021-04-22 06:45:50
【问题描述】:

所以我有一个循环,通过他们的键作为 ID 将 JSON 值附加到他们的输入中。我无法访问嵌套的 JSON 对象“tax_lines”并将其附加到相应的输入。也许我应该以不同的方式来做这件事?

数据.json

{
   "purchase_order" :[
     { 
        "id": "1",
        "external_number": "1000",
        "status": "Created",
        "tax_lines": [ 
            {
               "name": "GST",
               "rate": "0.05",
            }
        ],
        "price_list": [
            {
               "id": "msrp",
               "name": "retail price",
               "currency": "USD"
        ],
 .....etc
   ]
}
<input id="external_number" />
<input id="id"/>
<input id="status" />
<input id="tax_lines_name" />
<input id="tax_lines_rate" />


<script>
    const data_file = 'data.json';

    function fetchPO() {
        fetch(data_file).then(response => {
            return response.json();
        }).then((data => {

                for (var i = 0; i < data.purchase_orders.length; i++) {
                    data.purchase_orders.forEach((PODetails) => {
                        Object.keys(PODetails).map(value => {
                            document.getElementBy(value.replace(/ /g, "")).value = PODetails[value];
                        })

                        PODetails.tax_lines.forEach((tax) => {
                            Object.keys(tax).map(value => {
                                document.getElementByID(value.replace(/ /g, "")).value = tax[value];
                            })
                        })
                    })

                }
            })
        }

</script>

简而言之,如何将 json 对象的数据动态转换为 html 输入?

【问题讨论】:

  • 我确定这是一个错字,但你的 for 循环中有 var 1 = 0。
  • 您的“JSON”无效(缺少purchase_order" 上的",缺少几个结构的结束括号)。此外,一旦它被解析,它就不再是 JSON,它只是对象。见There's no such thing as a JSON Object

标签: javascript json nested-loops


【解决方案1】:

查看here 中的小提琴以获取完整示例。

你有很多错误:

  1. 使用 var i = 0 for 循环(因为您在内部使用了 foreach 循环)
  2. 有时您在第一个 Object.keys() 中的值项是一个对象,因此无法将其设置为输入字段。
  3. 当您不希望返回数组时,使用 .map() 是一种反模式。

要解决这个问题,您可以使用下面的 sn-p。

<input id="external_number" /><br />
<input id="id" /><br />
<input id="status" /><br />
<input id="tax_lines_name" /><br />
<input id="tax_lines_rate" /><br />


<script>
  async function get() {

    return `
{
  "purchase_order": [
    {
      "id": "1",
      "external_number": "10001",
      "status": "Created",
      "tax_lines": [
        {
          "name": "GST",
          "rate": "1"
        }
      ]
    }
  ]
}
        `;
  }

  function fetchPO() {
    get()
      .then(response => JSON.parse(response))
      .then(data => {

      data.purchase_order.forEach((PODetails) => {
        Object.keys(PODetails).forEach(value => {
                    if (value !== 'tax_lines') {
              document.getElementById(value.replace(/ /g, "")).value = PODetails[value];
          }
        })

        PODetails.tax_lines.forEach((tax) => {
          Object.keys(tax).forEach(value => {
            document.getElementById('tax_lines_' + value).value = tax[value];
          })
        }) 
      })


      })
      .catch(e => {
        console.log(e);
      })
  }

  fetchPO();

</script>


编辑:更新了代码段,因为 jsfiddle 不适合您。请查看您拥有的数据是否与我正在使用的数据在结构上相似。还修改了不使用 fetch 静态获取数据。

编辑 2:除了 cmets 部分中的响应之外,要实现完全动态的表单填充,您需要灵活处理输入 ID。 jsfiddle here 已更新并完全动态地处理输入 json。所以,一个对象:

{
   "id": "some-id",
   "name": "sbsatter",
   "grades": [
        {
            "course": "CS555",
            "grade": "A"
        },
        {
            "course": "CS666",
            "grade": "B"
        }
    ]

将动态生成带有 id 的输入:

  1. 身份证
  2. 姓名
  3. grades_0_course
  4. grades_0_grade
  5. grades_1_course
  6. grades_1_grade

递归处理json树更容易。您可能需要处理更具体的情况(例如输入为整数等)。这是实现该功能的功能:


        function handleObject(obj, name) {
          // console.log('Handling obj: ', obj, 'name: ', name);
          
          if (Object.prototype.toString.call(obj) === '[object String]') {
            // create input and update
            // document.getElementById(name + '_' + key).value = obj[key];
            var input = document.createElement('input');
            input.id = name.substring(1);
            input.value = obj;
            document.getElementById('container').appendChild(input);
            console.log(name.substring(1), obj);
          } 
          else if (Object.prototype.toString.call(obj) === '[object Object]') {
            Object.keys(obj).forEach(key => {
                handleObject(obj[key], name + "_" + key);
            });
          }
          else if (Object.prototype.toString.call(obj) === '[object Array]') {
            obj.forEach((object, idx) => {
              Object.keys(object).forEach(key => {
                handleObject(object[key], name + "_" + key + "_" + idx);
              });
            });
          }
        }
        
        handleObject(data, '');

希望这会有所帮助。

【讨论】:

  • 嗨,感谢您的解释和小提琴。不幸的是,我无法让它工作。代码在 forEach((tax) 处中断。我无法 console.log(tax); 即使我的 JSON 文件没有 NULL 值,我也会收到错误“TypeError: Cannot set property 'value' of null”。跨度>
  • @webdevelopern00b 我在这里更新了代码。您可以检查您的数据是否具有如上所示的格式?
  • 我之前更新了我的 JSON,很抱歉我应该提到它。我的 JSON 文件有其他嵌套的键和值。你给我的代码适用于我最初展示的 JSON 和你的小提琴,但不适用于我的整个文件。我需要能够遍历我的整个 JSON 文件并将值分配给它们各自的输入
  • @webdevelopern00b 您需要根据您拥有的其他字段进行调整。例如,您可以将 value !== 'tax_lines' 替换为更合适的条件。我更新了小提琴,所以你可以看看我是如何读取 json 中的每个字符串值的。您可以为其他 json obj 和数组使用单独的段(如 tax_lines 中所做的那样),或使其完全动态。除非您对上述数据有疑问,否则我建议您酌情更新问题。
  • @webdevelopern00b 我现在才看到更新的数据。你能具体说明你想要达到的目标吗?我认为通过对上面的代码进行一些修改,您可以正确处理它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
相关资源
最近更新 更多