迭代嵌套的对象数组,并在HTML表格中显示。

huangapple go评论78阅读模式
英文:

Iterate nested array of object and display in html table

问题

我有一个包含嵌套对象数组的 input 如下所示。

summary 是父级对象数组,run_type 是嵌套的数组。

let input = {
      "summary": [
          {
              "name": "Release",
              "run_type": [
                {
                  "environment": "6nc",
                  "type": "QA1"
                },
                {
                  "environment": "3nc",
                  "type": "QA2"
                }
              ]
          }
      ]
  }

我想要显示一个如下的表格。Name 字段有一个 rowspan 为 2,因为每个 summary 都有 2 个 run_type

------------------------------------
   Name    | Environment | RunType |
------------------------------------
  Release  |     6nc     |  QA1    |
           |     3nc     |  QA2    |
------------------------------------

要静态地显示这样的表格,可以这样做:

<table>
  <thead>
    <tr>
      <th>Vertical</th>
      <th>Environment</th>
      <th>RunType</th>
    </tr>
  </thead>
  <tbody>
  <tr>
    <td rowspan="2">Release</td>
    <td>6nc</td>
    <td>QA1</td>
  </tr>
  <tr>
    <td>3nc</td>
    <td>QA2</td>
  </tr>
  </tbody>
</table>

请问有人可以告诉我如何动态显示这个表格吗?我尝试了以下方式,但没有成功。问题在于我能够将 Name 列跨越 2 行,但是其他所有列都没有放置在同一 Name 部分的两行中。

<table>
  <thead>
    <tr>
      <th>Vertical</th>
      <th>Environment</th>
      <th>RunType</th>
    </tr>
  </thead>
  <tbody>
     {input?.summary?.map((project, indx) => {
       return (
         <tr>
           <td rowspan="2">{project?.name}</td>
             {project?.run_type?.map((runType, indx) => {
                return (
                  <>
                    <td>{runType.environment}</td>
                    <td>{runType.type}</td>
                  </>
                );
             })}
         </tr>
       );
     })}
  </tbody>
</table>
英文:

I have a below input with nested array of objects.

summary is parent array of objects and run_type is nested one.

let input = {
      &quot;summary&quot;: [
          {
              &quot;name&quot;: &quot;Release&quot;,
              &quot;run_type&quot;: [
                {
                  &quot;environment&quot;: &quot;6nc&quot;,
                  &quot;type&quot;: &quot;QA1&quot;
                },
                {
                  &quot;environment&quot;: &quot;3nc&quot;,
                  &quot;type&quot;: &quot;QA2&quot;
                }
              ]
          }
      ]
  }

I want to display a table like this. Name field has rowspan of 2 since there are 2 run_type for each summary

------------------------------------
   Name    | Environment | RunType |
------------------------------------
  Release  |     6nc     |  QA1    |
           |     3nc     |  QA2    |
------------------------------------

To display a table like this statically, i can do this way

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Vertical&lt;/th&gt;
      &lt;th&gt;Environment&lt;/th&gt;
      &lt;th&gt;RunType&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
  &lt;tr&gt;
    &lt;td rowspan=&quot;2&quot;&gt;Release&lt;/td&gt;
    &lt;td&gt;6nc&lt;/td&gt;
    &lt;td&gt;QA1&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;3nc&lt;/td&gt;
   &lt;td&gt;QA2&lt;/td&gt;
  &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

can someone please let me know how to dynamically show this table. I tried using this way but was unsuccessful. the problem is that i am able to rowspan Name column into 2 rows but all other columns are not being placed as two rows within that same Name section

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Vertical&lt;/th&gt;
      &lt;th&gt;Environment&lt;/th&gt;
      &lt;th&gt;RunType&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
     {input?.summary?.map((project, indx) =&gt; {
       return (
         &lt;tr&gt;
           &lt;td rowspan=&quot;2&quot;&gt;{project?.name}&lt;/td&gt;
             {project?.run_type?.map((runType, indx) =&gt; {
                return (
                  &lt;&gt;
                    &lt;td&gt;{runType.environment}&lt;/td&gt;
                    &lt;td&gt;{runType.type}&lt;/td&gt;
                  &lt;/&gt;
                );
             })}
         &lt;/tr&gt;
       );
     })}
  &lt;/tbody&gt;
&lt;/table&gt;

答案1

得分: 2

问题出在你使用了一个单独的<tr>元素来迭代run_type环境和类型。这导致了表格结构的错误渲染。

以下是你可以修改代码的方式:

<tbody>
  {input?.summary?.map((project, projectIndex) => (
    <>
      {project?.run_type?.map((runType, runTypeIndex) => (
        <tr key={`${projectIndex}-${runTypeIndex}`}>
          {runTypeIndex === 0 ? (
            <td rowspan={project.run_type.length}>{project.name}</td>
          ) : null}
          <td>{runType.environment}</td>
          <td>{runType.type}</td>
        </tr>
      ))}
    </>
  ))}
</tbody>

希望对你有帮助!

英文:

The problem arises from the fact that you're using a single &lt;tr&gt; element to iterate through both the run_type environments and types. This leads to an incorrect rendering of the table structure.

Here's how you can modify your code to achieve this:

  &lt;tbody&gt;
    {input?.summary?.map((project, projectIndex) =&gt; (
      &lt;&gt;
        {project?.run_type?.map((runType, runTypeIndex) =&gt; (
          &lt;tr key={`${projectIndex}-${runTypeIndex}`}&gt;
            {runTypeIndex === 0 ? (
              &lt;td rowspan={project.run_type.length}&gt;{project.name}&lt;/td&gt;
            ) : null}
            &lt;td&gt;{runType.environment}&lt;/td&gt;
            &lt;td&gt;{runType.type}&lt;/td&gt;
          &lt;/tr&gt;
        ))}
      &lt;/&gt;
    ))}
  &lt;/tbody&gt;

答案2

得分: 1

你需要根据每个run_type生成一个<tr>,所以内部循环应该生成<tr>,而不是外部循环。由于带有rowspan<td>应该只在项目的第一行创建,可以使用条件表达式indx==0来生成它:

input.summary?.map((project) =>
    project.run_type?.map((runType, indx, {length}) =>
        <tr>
           {indx == 0 ? <td rowspan={length}>{project.name}</td> : ''}
           <td>{runType.environment}</td>
           <td>{runType.type}</td>
        </tr>
    )
)
英文:

You need a &lt;tr&gt; per run_type, so the inner loop should generate the &lt;tr&gt;, not the outer. As the &lt;td&gt; with rowspan should only be created for the first row of the project, use a conditional expression with indx==0 to generate it:

input.summary?.map((project) =&gt;
    project.run_type?.map((runType, indx, {length}) =&gt;
        &lt;tr&gt;
           {indx == 0 ? &lt;td rowspan={length}&gt;{project.name}&lt;/td&gt; : &#39;&#39;}
           &lt;td&gt;{runType.environment}&lt;/td&gt;
           &lt;td&gt;{runType.type}&lt;/td&gt;
        &lt;/tr&gt;
    )
)

答案3

得分: 1

我会将数据首先转换为一个包含文本和行跨度信息的矩阵。

现在你可以使用该矩阵来渲染<tbody>

let input = {
  "summary": [{
    "name": "Release",
    "run_type": [{
      "environment": "6nc",
      "type": "QA1"
    }, {
      "environment": "3nc",
      "type": "QA2"
    }]
  }]
};

const tableData = input.summary.flatMap(({ name, run_type }) => {
  return run_type.map(({ environment, type }, index) => {
    const row = [];
    if (index === 0) {
      row.push({ text: name, rowSpan: run_type.length });
    }
    row.push({ text: environment });
    row.push({ text: type });
    return row;
  });
});

document.querySelector('.data tbody').insertAdjacentHTML('afterbegin', `
  ${tableData.map(row =>
    `<tr>${row.map(col =>
      `<td rowSpan=${col.rowSpan ?? 1}>${col.text}</td>`)
    .join('')}</tr>`)
  .join('')}
`);

table.data {
  border-collapse: collapse;
}

table.data, .data th, .data td {
  border: thin solid grey;
}

.data th, .data td {
  padding: 0.5rem;
}

.data th {
  background: rgba(0, 0, 0, 0.125);
}
<table class="data">
  <thead>
    <tr>
      <th>Name</th>
      <th>Environment</th>
      <th>RunType</th>
    </tr>
  </thead>
  <tbody></tbody>
</table>
英文:

I would transform the data into a matrix of text and row-span information first.

Now you can use the matrix to just render the &lt;tbody&gt;.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

let input = {
  &quot;summary&quot;: [{
    &quot;name&quot;: &quot;Release&quot;,
    &quot;run_type&quot;: [{
      &quot;environment&quot;: &quot;6nc&quot;,
      &quot;type&quot;: &quot;QA1&quot;
    }, {
      &quot;environment&quot;: &quot;3nc&quot;,
      &quot;type&quot;: &quot;QA2&quot;
    }]
  }]
};

const tableData = input.summary.flatMap(({ name, run_type }) =&gt; {
  return run_type.map(({ environment, type }, index) =&gt; {
    const row = [];
    if (index === 0) {
      row.push({ text: name, rowSpan: run_type.length });
    }
    row.push({ text: environment });
    row.push({ text: type });
    return row;
  });
});

document.querySelector(&#39;.data tbody&#39;).insertAdjacentHTML(&#39;afterbegin&#39;, `
  ${tableData.map(row =&gt;
    `&lt;tr&gt;${row.map(col =&gt;
      `&lt;td rowSpan=${col.rowSpan ?? 1}&gt;${col.text}&lt;/td&gt;`)
    .join(&#39;&#39;)}&lt;/tr&gt;`)
  .join(&#39;&#39;)}
`);

<!-- language: lang-css -->

table.data {
  border-collapse: collapse;
}

table.data, .data th, .data td {
  border: thin solid grey;
}

.data th, .data td {
  padding: 0.5rem;
}

.data th {
  background: rgba(0, 0, 0, 0.125);
}

<!-- language: lang-html -->

&lt;table class=&quot;data&quot;&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Name&lt;/th&gt;
      &lt;th&gt;Environment&lt;/th&gt;
      &lt;th&gt;RunType&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;&lt;/tbody&gt;
&lt;/table&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年8月8日 21:04:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76859861.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定