英文:
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 = {
"summary": [
{
"name": "Release",
"run_type": [
{
"environment": "6nc",
"type": "QA1"
},
{
"environment": "3nc",
"type": "QA2"
}
]
}
]
}
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
<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>
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
<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>
答案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 <tr>
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:
<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>
答案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 <tr>
per run_type
, so the inner loop should generate the <tr>
, not the outer. As the <td>
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) =>
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>
)
)
答案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 <tbody>
.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
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('')}
`);
<!-- 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 -->
<table class="data">
<thead>
<tr>
<th>Name</th>
<th>Environment</th>
<th>RunType</th>
</tr>
</thead>
<tbody></tbody>
</table>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论