@supeeeee_r_man
Начинающий веб-разработчик

Как вывести вложенные данные в виде таблицы с объединёнными ячейками?

Есть массив следующего вида:
"clouds": [{
      "cloud": "cloud",
      "shards": [{
          "repository_size_gb": 3071,
          "repository": "VBR",
          "jobs": [{
              "job": "VBR1",
              "job_description": "Каждый день инкремент, хранить 6 точек",
              "backup_name": "VBR-NORD-152-Getblogger01",
              "backup_size_gb": 616,
            },{
              "job": "VBR2",
              "job_description": "Каждый день инкремент, хранить 6 точек",
              "backup_name": "VBR-NORD-152-Getblogger01",
              "backup_size_gb": 616,
            },{
              "job": "VBR3",
              "job_description": "Каждый день инкремент, хранить 6 точек",
              "backup_name": "VBR-NORD-152-Getblogger01",
              "backup_size_gb": 616,
            }]
        }]
    }]

Надо отобразить его содержимое в виде таблицы:

2iIdB.png
Всё, что пришло в голову на данный момент - это:

return (
  <table>
    <tbody>
      <tr>
        {header.map((el, i) => <th key={i}> <FormattedMessage id={el.title}/> </th>)}
      </tr>
    </tbody>
    <tbody>
      {this.props['vmBackup'].map((el, i) => (
        <tr key={i}>
          {header.map((col, j) => (
            <td className={col.right ? cellClsRight : cellCls} key={i + ':' + j}>
              <span> {el[col.col]} </span>
            </td>
          ))}
        </tr>
      ))}
    </tbody>
  </table>
)

И выводится:

7xDpM.png
  • Вопрос задан
  • 2978 просмотров
Пригласить эксперта
Ответы на вопрос 5
miraage
@miraage
Старый прогер
- напишите функцию, которая перегонит данную структуру в нормальную матрицу
- отрендерите простую таблицу без лишней логики
- оберните транфсормацию в useMemo, если будут проседания по производительности (optional)

Посыл в том, что UI layer не должен страдать из-за того, что данные не в том формате.
Ответ написан
@szubtsovskiy
Вам поможет rowSpan. В примере я засунул данные в state, но вы продолжайте брать из props:

render() {
    return (
      <table>
        <tbody>
          <tr>
            {new Array(8).fill(0).map((el, i) => <th key={i}>TEXT</th>)}
          </tr>
        </tbody>
        <tbody>
          {this.state['vmBackup']['clouds'].flatMap(cloud => {
            return cloud.shards.map(shard => {
              const jobCount = shard['jobs'].length;
              return shard['jobs'].map((job, i) => {
                if (i == 0) {
                  return (
                    <tr key={i}>
                      <td rowSpan={jobCount}>{cloud['cloud']}</td>
                      <td rowSpan={jobCount}>{shard['repository']}</td>
                      <td rowSpan={jobCount}>{shard['repository_size_gb']}</td>
                      <td>{job['job']}</td>
                      <td>{job['job_description']}</td>
                      <td>{job['backup_name']}</td>
                      <td>{job['backup_size_gb']}</td>
                      <td>5</td>
                    </tr>
                  )
                } else {
                  return (
                    <tr key={i}>
                      <td>{job['job']}</td>
                      <td>{job['job_description']}</td>
                      <td>{job['backup_name']}</td>
                      <td>{job['backup_size_gb']}</td>
                      <td>5</td>
                    </tr>
                  )
                }              	
              })
            })
          })}
        </tbody>
      </table>
    )
  }
Ответ написан
NooNoo
@NooNoo
Yep
Можно воспользоваться <template>. Создаете 'компонент', потом уже с помощью js подставляете данные
Ответ написан
Комментировать
@AShvejnov
Есть куча готовых jQuery плагинов/компонентов, которые рисуют всевозможные таблички. Большинство из них как раз на входе умеют принимать данные в JSON-е, то бишь, в виде массива как у вас. Поищите просто наиболее подходящее готовое решение (гугл -> "jQuery data grids") и не тратьте время на изобретение велосипеда.
Ответ написан
Комментировать
0xD34F
@0xD34F Куратор тега React
const rowspan = shards => shards.reduce((acc, n) => acc + n.jobs.length, 0);

<table>
  <thead>
    <tr>{HEADERS.map(n => <th>{n}</th>)}</tr>
  </thead>
  <tbody>{
    DATA.flatMap(({ cloud, shards }) =>
    shards.flatMap((shard, iShard) =>
    shard.jobs.map((job, iJob) =>
      <tr>
        {!iShard && !iJob && <td rowSpan={rowspan(shards)}>{cloud}</td>}
        {!iJob && <td rowSpan={shard.jobs.length}>{shard.repository}</td>}
        {!iJob && <td rowSpan={shard.jobs.length}>{shard.repository_size_gb}</td>}
        <td>{job.job}</td>
        <td>{job.job_description}</td>
        <td>{job.backup_name}</td>
        <td>{job.backup_size_gb}</td>
      </tr>
    )))}
  </tbody>
</table>

https://jsfiddle.net/0ycjmnf3/
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы