动态JavaScript表不会显示数组的迭代

时间:2018-12-10 21:08:55

标签: javascript html arrays json multidimensional-array

很抱歉这个问题有多么简单...。 函数tablefromDb();从console.log中上面的数据数组迭代并正确生成数据,但是javaScript表生成器仅显示最后一次迭代。 Whhhhhyyyyyyy javascript动态HTML表生成器不会像console.log中那样显示所有迭代吗?我花了三天的时间才能到达这一点,但我无法超越这一点。...

    var data = 
    [
        {
          "deviceOne":
            {
              "input": ["oneInOne", "oneInTwo","oneInThree","oneInFour"],
              "output": ["oneOutOne", "oneOutTwo", "oneOutThree"]
            }
        },
        {
            "deviceTwo":
              {
                "input": ["twoInOne", "twoInTwo","twoInThree","twoInFour"],
                "output": ["twoOutOne", "twoOutTwo", "twoOutThree", "twoOutFour", "twoOutFive"]
              }
          }
    ]

function tablesFromDb(){

  for(j=0; j<data.length; j++){
    var tableTop = "<form><table>";
    var tableHeader = "<tr><th>No</th><th>Input</th><th>Output</th>";
    var tableBottom = "</table></form>";
    var insideArray = data[j];
        
    for(deviceTitle in insideArray){
    var fbdCaption = "<caption>" + deviceTitle + "</caption>\n";
    console.log(deviceTitle);

      for(k=0; k<insideArray[deviceTitle]["input"].length; k++){
      var fdbCellData = "<tr><td>" + (k+1) + "</td>" + "<td>" + insideArray[deviceTitle]["input"][k] + "</td>" + "<td>" + insideArray[deviceTitle]["output"][k] + "</td></tr>\n";
      console.log(insideArray[deviceTitle]["input"][k]);
      console.log(insideArray[deviceTitle]["output"][k]);
      }
    }
    document.getElementById('container').innerHTML = tableTop + fbdCaption + tableHeader + fdbCellData + tableBottom;
  }
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>title</title>
  </head>
  <body onload="tablesFromDb();">
    
    <div id="container"></div>

  <script src=js.js></script>
  </body>
</html>

更新:我有部分工作,但是我仍然无法理解此循环的实际工作方式。如何使最后一个for循环迭代(我想是)上述循环以显示两个表的正确内容。...我不是很擅长此事。...

var data = [
  {
    deviceOne: {
      input: ["oneInOne", "oneInTwo", "oneInThree", "oneInFour"],
      output: ["oneOutOne", "oneOutTwo", "oneOutThree"]
    }
  },
  {
    deviceTwo: {
      input: ["twoInOne", "twoInTwo", "twoInThree", "twoInFour"],
      output: ["twoOutOne", "twoOutTwo", "twoOutThree", "twoOutFour"]
    }
  }
];

    //var fdbCellData = "";
function tablesFromDb() {
  var tableTop = "";
  var tableBottom = "";
  var fdbCellData = "";
  
  for (j = 0; j < data.length; j++) {
    var insideArray = data[j];
    //var fdbCellData = "";

    for(var deviceTitle in insideArray){
    tableTop += "<form><table border=1><caption>" + deviceTitle + "</caption>";
    tableTop += "<tr><th>No</th><th>Input</th><th>Output</th>";
    tableBottom += "</table></form>";
    console.log(deviceTitle);
    //var fdbCellData = "";
  
    for (k = 0; k < insideArray[deviceTitle].input.length; k++) {
      fdbCellData += "<tr><td>" + (k + 1) + "</td>";
      fdbCellData += "<td>" + insideArray[deviceTitle].input[k] + "</td>";
      fdbCellData += "<td>" + insideArray[deviceTitle].output[k] + "</td></tr>";
    }
    }

  }
  document.getElementById("container").innerHTML =
    tableTop + fdbCellData + tableBottom;
}
<body onload="tablesFromDb();">
    
    <div id="container"></div>

  </body>

3 个答案:

答案 0 :(得分:1)

您需要在循环外部声明fbdCaption,并在循环内部对其进行累加。在您的第二次尝试中,仍然存在一个问题:

两个表“ tops”的HTML连接在一个专用变量中,然后以这种方式输出,这意味着您在输出中将两个tops紧接在一起,而数据行不在第一个top之下。其他两个收集HTML的变量也会发生类似的情况。这也意味着输出的HTML结构实际上是无效的。

解决这个问题并不难,但是我更喜欢另一种构建HTML元素的方法:使用DOM方法。

此外,在一种情况下,输出值多于输入值。否则,您的输出将不完整。

最后,您使用了一些迭代变量,而没有明确定义它们。这使它们具有全局性。

工作代码如下:

// A helper function to append one table-row containing the given texts (array)
function insertRowWithTexts(table, tag, texts) {
    const row = table.insertRow();
    for (const text of texts) {
        const elem = document.createElement(tag); // Either a TD or a TH
        elem.textContent = text === undefined ? "" : text;
        row.appendChild(elem);
    }
}

function tablesFromDb(data) {
    for (const obj of data) {
        for (const deviceTitle in obj) {
            const { input, output } = obj[deviceTitle];
            const table = document.createElement("table");
            table.createCaption().textContent = deviceTitle;
            insertRowWithTexts(table, "th", ["No", "Input", "Output"]);
            for (let k = 0; k < Math.max(input.length, output.length); k++) {
                insertRowWithTexts(table, "td", [k+1, input[k], output[k]]);
            }
            document.getElementById("container").appendChild(table);
        }
    }
}

var data = [{deviceOne: {input: ["oneInOne", "oneInTwo", "oneInThree", "oneInFour"], output: ["oneOutOne", "oneOutTwo", "oneOutThree"]}},{deviceTwo: {input: ["twoInOne", "twoInTwo", "twoInThree", "twoInFour"],output: ["twoOutOne", "twoOutTwo", "twoOutThree", "twoOutFour"]}}];

document.addEventListener('DOMContentLoaded', () => tablesFromDb(data));
td, th {
    border: 1px solid;
}
<div id="container"></div>

在HTML Element对象上使用textContent =的优点是,它可以照顾到可能需要转义的所有字符。例如,如果一个文本包含volt&ampere,它将被正确地转义,因此它也可以那样渲染,而不像“ volt&ere”或其他东西。

答案 1 :(得分:0)

需要在循环外定义单元格数据。试试这个:

function tablesFromDb(){
    for(j=0; j<data.length; j++){
        var tableTop = "<form><table>";
        var tableHeader = "<tr><th>No</th><th>Input</th><th>Output</th>";
        var tableBottom = "</table></form>";
        var insideArray = data[j];
        var fbdCaption = "<caption>" + deviceTitle + "</caption>\n";
        var fdbCellData = "";
        for(deviceTitle in insideArray){
           for(k=0; k<insideArray[deviceTitle]["input"].length; k++){
              fdbCellData += "<tr><td>" + (k+1) + "</td>" + "<td>" + insideArray[deviceTitle]["input"][k] + "</td>" + "<td>" + insideArray[deviceTitle]["output"][k] + "</td></tr>\n";
           }
        }
        document.getElementById('container').innerHTML = tableTop + fbdCaption + tableHeader + fdbCellData + tableBottom;
      }
    }

答案 2 :(得分:0)

最后成功了!!感谢@trincot和我的儿子为我指出了正确的方向...。对于那些感兴趣的人,我稍微更改了数据结构,使其更易于管理。其余的您可以在代码中看到。

const data = [
  {
    name: "deviceOne",
    input: ["oneInOne", "oneInTwo", "oneInThree", "oneInFour"],
    output: ["oneOutOne", "oneOutTwo", "oneOutThree"]
  },
  {
    name: "deviceTwo",
    input: ["twoInOne", "twoInTwo", "twoInThree", "twoInFour"],
    output: ["twoOutOne", "twoOutTwo", "twoOutThree", "twoOutFour"]
  },
    {
    name: "deviceThree",
    input: ["threeInOne", "threeInTwo", "threeInThree", "threeInFour"],
    output: ["threeOutOne", "threeOutTwo", "threeOutThree", "threeOutFour"]
  }
];


const container = document.getElementById('container');

for (var i = 0;  i < data.length; i++) {

let title = document.createElement('caption');
let table = document.createElement('table');
table.setAttribute('border', 1);
  var row = table.insertRow(0);
  var cell1 = row.insertCell(0);
  var cell2 = row.insertCell(1);
  var cell3 = row.insertCell(2);
  cell1.innerHTML = 'No';
  cell2.innerHTML = 'Input';
  cell3.innerHTML = 'Output';
    
	for (var j = 0; j < data[i].input.length; j++) {
  	var dataRow = table.insertRow();
    var dataCell1 = dataRow.insertCell();
    var dataCell2 = dataRow.insertCell();
    var dataCell3 = dataRow.insertCell();
    dataCell1.innerHTML = j+1;
    dataCell2.innerHTML = data[i].input[j]
    dataCell3.innerHTML = data[i].output[j]

  }
  
  title.innerText = data[i].name;
  
  container.appendChild(title);
  container.appendChild(table);

}
<div id="container">

</div>