javascript html表格中循环数据时如何多级合并行

czq61nw1  于 2023-03-21  发布在  Java
关注(0)|答案(3)|浏览(212)

我有像下面这样的数据与随机行数(三级),我想循环这个数据显示如下表
第一节第一节第一节第一节第一次
enter image description here

  1. const myData = [
  2. {
  3. subject: "Math",
  4. class: [
  5. {
  6. name: "Math-01",
  7. results: [
  8. {student: "jame",score: "10"},
  9. {student: "kelvin",score: "4"},
  10. { student: "smith",score: "8"}
  11. ]
  12. },
  13. {
  14. name: "Math-02",
  15. results: [
  16. { student: "joe",score: "8"},
  17. {student: "yassou",score: "8"}
  18. ]
  19. }
  20. ]
  21. },
  22. {
  23. subject: "History",
  24. class: [
  25. {
  26. name: "History-01",
  27. results: [
  28. {student: "zoe", score: "6"},
  29. {student: "jame", score: "8"},
  30. {student: "bean", score: "9"}
  31. ]
  32. },
  33. {
  34. name: "History-02",
  35. results: [
  36. {student: "luffy", score: "10"},
  37. ]
  38. }
  39. ]
  40. },
  41. {
  42. subject: "literature",
  43. class: [
  44. {
  45. name: "literature-01",
  46. results: [
  47. {student: "nami", score: 5}
  48. ]
  49. },
  50. {
  51. name: "literature-02",
  52. results: [
  53. {student: "zoro", score: 3}
  54. ]
  55. },
  56. {
  57. name: "literature-03",
  58. results: [
  59. {student: "shank", score: 5}
  60. ]
  61. }
  62. ]
  63. }
  64. ]

我尝试了这种方法https://codesandbox.io/s/material-ui-table-demo-with-row-span-dq1w6,但它只适用于级别2
下面是我第2级代码,它可以工作

我继续将此逻辑应用于第3级,但它无法正常工作

任何人都可以帮助我用另一种方法,我希望表看起来像第一张图片从myData。
(*)注意:myData可以有更多的数据与不同的行数,所以我希望能够建立合并单元格表动态(但它仍然是相同的格式)
非常感谢。

lp0sw83n

lp0sw83n1#

  1. const myData = [
  2. {
  3. subject: "Math",
  4. class: [
  5. {
  6. name: "Math-01",
  7. results: [
  8. {student: "jame",score: "10"},
  9. {student: "kelvin",score: "4"},
  10. { student: "smith",score: "8"}
  11. ]
  12. },
  13. {
  14. name: "Math-02",
  15. results: [
  16. { student: "joe",score: "8"},
  17. {student: "yassou",score: "8"}
  18. ]
  19. }
  20. ]
  21. },
  22. {
  23. subject: "History",
  24. class: [
  25. {
  26. name: "History-01",
  27. results: [
  28. {student: "zoe", score: "6"},
  29. {student: "jame", score: "8"},
  30. {student: "bean", score: "9"}
  31. ]
  32. },
  33. {
  34. name: "History-02",
  35. results: [
  36. {student: "luffy", score: "10"},
  37. ]
  38. }
  39. ]
  40. },
  41. {
  42. subject: "literature",
  43. class: [
  44. {
  45. name: "literature-01",
  46. results: [
  47. {student: "nami", score: 5}
  48. ]
  49. },
  50. {
  51. name: "literature-02",
  52. results: [
  53. {student: "zoro", score: 3}
  54. ]
  55. },
  56. {
  57. name: "literature-03",
  58. results: [
  59. {student: "shank", score: 5}
  60. ]
  61. }
  62. ]
  63. },
  64. {
  65. subject: "literature",
  66. class: [
  67. {
  68. name: "literature-01",
  69. results: []
  70. },
  71. {
  72. name: "literature-02",
  73. results: [ {student: "zoro", score: 3} ]
  74. },
  75. {
  76. name: "literature-03",
  77. results: [ {student: "shank", score: 5} ]
  78. }
  79. ]
  80. }
  81. ];
  82. function App() {
  83. return (
  84. <table>
  85. {
  86. myData.map((record, i) => {
  87. let subjectHandled = false;
  88. return record.class.map((course, j) => {
  89. return course.results.map((r, k) => {
  90. let subjectTdEl;
  91. if (!subjectHandled && k === 0) {
  92. let resultsCount = 0;
  93. record.class.forEach((c) => {
  94. resultsCount += c.results.length;
  95. });
  96. subjectTdEl = <td rowSpan={resultsCount}>{record.subject}</td>
  97. subjectHandled = true;
  98. }
  99. let courseTdEl;
  100. if (k === 0) {
  101. courseTdEl = <td rowSpan={course.results.length}>{course.name}</td>;
  102. }
  103. return (
  104. <tr key={k}>
  105. {subjectTdEl}
  106. {courseTdEl}
  107. <td>{r.student}</td>
  108. <td>{r.score}</td>
  109. </tr>
  110. );
  111. });
  112. });
  113. })
  114. }
  115. </table>
  116. );
  117. }
  118. ReactDOM.render(<App />, document.getElementById('root'));
  1. table {
  2. font-family: verdana;
  3. border-collapse: collapse;
  4. }
  5. table, th, td {
  6. padding: 10px;
  7. border: 1px solid black;
  8. text-align: center;
  9. }
  1. <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
  2. <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
  3. <div id="root"></div>
展开查看全部
gpnt7bae

gpnt7bae2#

我用javascript做了这个数据表。你可以检查和参考它。

  1. function getData(){
  2. const myData = [
  3. {
  4. subject: "Math",
  5. class: [
  6. {
  7. name: "Math-01",
  8. results: [
  9. {student: "jame",score: "10"},
  10. {student: "kelvin",score: "4"},
  11. {student: "smith",score: "8"}
  12. ]
  13. },
  14. {
  15. name: "Math-02",
  16. results: [
  17. {student: "joe",score: "8"},
  18. {student: "yassou",score: "8"}
  19. ]
  20. }
  21. ]
  22. },
  23. {
  24. subject: "History",
  25. class: [
  26. {
  27. name: "History-01",
  28. results: [
  29. {student: "zoe", score: "6"},
  30. {student: "jame", score: "8"},
  31. {student: "bean", score: "9"}
  32. ]
  33. },
  34. {
  35. name: "History-02",
  36. results: [
  37. {student: "luffy", score: "10"},
  38. ]
  39. }
  40. ]
  41. },
  42. {
  43. subject: "literature",
  44. class: [
  45. {
  46. name: "literature-01",
  47. results: [
  48. {student: "nami", score: 5}
  49. ]
  50. },
  51. {
  52. name: "literature-02",
  53. results: [
  54. {student: "zoro", score: 3}
  55. ]
  56. },
  57. {
  58. name: "literature-03",
  59. results: [
  60. {student: "shank", score: 5}
  61. ]
  62. }
  63. ]
  64. }
  65. ];
  66. let html ="<table border='1|1'>";
  67. html +=`
  68. <tr>
  69. <th>Subject</th>
  70. <th>Class</th>
  71. <th>Student</th>
  72. <th>Score</th>
  73. </tr>`;
  74. myData.forEach((item) => {
  75. let subject = item.subject;
  76. let row = subject == 'Math' ? 5 : subject == 'History' ? 4 : 3;
  77. html += `<th rowspan="${row}"> ${subject} </th>`;
  78. item.class.forEach((item2) => {
  79. html += `<th rowspan="${item2.results.length}">${item2.name}</th>`;
  80. item2.results.forEach((item3 => {
  81. let name = item3.student;
  82. let score = item3.score;
  83. html += `<td>${name}</td><td>${score}</td></tr>`;
  84. }))
  85. })
  86. })
  87. html += "</table>";
  88. document.body.innerHTML = html;
  89. }
  1. <body onLoad="getData()">
展开查看全部
kqlmhetl

kqlmhetl3#

我在reactjs方面没有经验,但我可以给予你一些建议,告诉你如何构建数据库来有效地处理这个问题。我过去用另一个处理树数据的Javascript框架做过这个。
您正在对数据集进行硬编码,每个级别都是不同的类型。这里的技巧是对数据集进行软编码以动态处理数据。因此,如果数据发生更改,则不必更改代码。如果您希望数据集真正具有动态性,我建议将数据模型更改为下面的模型。如果数据库无法更改,您可以编写一个视图,查询当前数据模型,使其看起来像新的数据模型。
创建一个名为node_hierarchy的表,其中包含parent_id、child_id和node_id。这些值是任意的,在将数据插入数据库时可以是任何唯一的值。此表的PK可以是parent_id和child_id的组合键。或者,您可以将concat_id作为PK,将它们串在一起,并使用单个列而不是两个列作为PK(复合)。还有一个名为node的表,其中包含node_id、node_type和node_value列。这样,您可以添加其他类型和多个级别,而无需担心更改源代码。每个表中的node_id成为关联,一个是node表中的FK,另一个是node_hierarchy表中的PK。
查询数据时,如果在树中重复某个节点,请确保节点的ID是parent_id + child_id的串联(hierarchy).意味着节点有多个父节点.如果节点没有多个父节点,忽略这一点.如果你没有串联id,你将在树中有重复的id,并可能在渲染时导致异常.通常情况下客户端树id需要唯一,因此使用reactjs进行验证。在构建数据集时,将concat_id添加到JSON数据中的节点,但在渲染时隐藏concat_id。仅用于参考。
查询数据时,您可以添加node_level,但也可以将其隐藏在渲染数据集中。该级别不应位于数据库中,因为它是基于具有唯一parent_id的node_hierarchy记录的数量动态变化的。如果与数据库中的数据集级别(node_level)不同,您甚至可以使用另一个render_level。
示例:

  1. node_type, node_value [, concat_id, node_level, render_level]
  2. ----------------------- node_level = 0 ; render_level (ignored in query) ---------
  3. root, Subject
  4. root, Class
  5. root, Student
  6. root, Score
  7. ----------- node_level = 1 ; render_level (ignored in query) ------------
  8. Subject, Math
  9. Subject, History
  10. Subject, Literature
  11. ------------------------ node_level = 2 ; render_level = 1 -------------
  12. Class, Math-01
  13. Class, Math-02
  14. etc...
  15. ------------------- node_level = 3 ; render_level = 2 ------------
  16. Student, Jame
  17. Student, Calvin
  18. etc...
  19. ------------------- node_level = 4 ; render_level = 3 --------------
  20. Score, 10
  21. Score, 4
  22. etc...

在不知道你使用的数据库类型的情况下,我不能给予你任何代码来编写递归查询来拉取数据集。例如,如果你使用PostgreSQL,那么执行以下操作:
您对node_hierarchy的查询(或者node_tree,如果你这么叫的话),应该使用WITH RECURSIVE将祖先和后代联合到一个数据集中。node_level和render_level将是动态数据列值。使用INNER JOIN将节点表连接到node_hierarchy表(node.node_id = node_hierarchy.node_id)来获取静态数据列值。我使用单词“dynamic”和“static”的上下文是基于数据的检索。这允许您的静态数据(检索)在数据库中变得随着数据的存储/维护的上下文而动态。
JSON看起来像这样。要知道JSON在键/值对的值部分有变量,但插值后JSON的渲染HTML将不会(并且只会有值)。示例是this.nodes.node_value。这只是显示检索值的位置。一些JavaScript客户端框架允许JSON插值中的变量,有些则不允许。使用ReactJS进行验证。I'我这里不插入键。例如,name可以是this.parent_node.node_value(或者this.parent_node_value,如果它存在的话)。或者,例如,节点可以基于级别定义。所以节点将是级别2的“结果”。所以你可以在一些JS客户端框架中插入键或值。

  1. const myData = [
  2. {
  3. concat_id: "0-1",
  4. parent_id: "0",
  5. child_id: "1",
  6. render_level: "1",
  7. subject: node_value <---- dynamically becomes "Math"
  8. nodes: [
  9. {
  10. concat_id: "1-2",
  11. parent_id: "1",
  12. child_id: "2",
  13. render_level: "2",
  14. name: node_value, < ---- dynamically becomes "Math-01"
  15. nodes: [
  16. {
  17. concat_id: "2-3",
  18. parent_id: "2",
  19. child_id: "3",
  20. render_level: "3",
  21. student: node_value, <---------- becomes "Jame"
  22. score: this.nodes.node_value <--------- becomes "10"
  23. },
  24. {
  25. concat_id: "2-4",
  26. parent_id: "2",
  27. child_id: "4",
  28. render_level: "3",
  29. student: node_value, <---------- becomes "Kelvin"
  30. score: this.nodes.node_value <--------- becomes "4"
  31. },
  32. {
  33. concat_id: "2-5",
  34. parent_id: "2",
  35. child_id: "5",
  36. render_level: "3",
  37. student: node_value, <---------- becomes "Smith"
  38. score: this.nodes.node_value <--------- becomes "8"
  39. }
  40. ]
  41. }
  42. ]
  43. ]

实际上,node_type可以省略。node_type将有自己的节点。在我提供的数据集中,node_type将是父节点(祖先)的node_value,node_value将是子节点(后代)。
祝你好运我的朋友。

展开查看全部

相关问题