Append nested JSON object key to loop - 将 JSON 动态转换为输入字段值

Append nested JSON object key to loop - Convert JSON to input field values dynamically

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

data.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 输入?

查看 here 中的 fiddle 以获得完整示例。

您有一些错误:

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

要解决此问题,您可以使用下面的代码段。

<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:除了评论部分的回复之外,要实现完全动态的表单填写,您需要灵活处理输入 ID。 jsfiddle here 已更新并完全动态地处理输入 json。所以,一个对象:

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

将动态生成 ID 为:

的输入
  1. id
  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, '');

希望对您有所帮助。