You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring+Thymeleaf实现飞盘高尔夫球场动态列表格展示问题

解决方案

一、优化数据结构(推荐)

当前ParList用18个独立字段(parHole1到parHole18)的设计不够灵活,建议改为列表存储洞数数据,让洞数直接由列表长度决定:

// 修改ParList类
public class ParList {
    private Long parListId;
    // 用List存储每个洞的par值
    private List<String> pars;
    // 关联字段、getter/setter
}

// Course类保持关联关系不变
public class Course {
    private Long id;
    private String name;
    private List<ParList> parLists;
    // getter/setter
}

这种设计下,动态生成表格只需循环pars列表即可,逻辑更简洁。

如果暂时不想修改实体类,可采用下面的现有结构适配方案。

二、现有结构下的Thymeleaf动态实现

1. 动态生成球场表格(显示端)

核心逻辑:统计parHole1到parHole18中非空字段的数量作为实际洞数,再循环生成对应列的表头和内容。

<div class="container" th:each="course : ${courses}">
    <div class="border">
        <div id="courseDetails" class="row">
            <div class="col-sm-4">
                <p><strong>Course Name:</strong>
                    <a th:text="${course.name}"></a>
                </p>
            </div>
        </div>
    </div>
    <div>
        <table th:each="par : ${course.parLists}" id="courseInfo" class="table table-bordered w-auto">
            <tr>
                <th th:text="'Hole'"></th>
                <!-- 动态生成表头:过滤空值字段,只显示有数据的洞数 -->
                <th th:each="i : ${#numbers.sequence(1, 18)}" 
                    th:if="${par['parHole' + i] != null && !par['parHole' + i].isEmpty()}"
                    th:text="'#' + ${i}"></th>
                <th>Actions</th>
            </tr>
            <tr>
                <td th:text="'Par'"></td>
                <!-- 动态生成Par列:对应非空的parHole字段 -->
                <td th:each="i : ${#numbers.sequence(1, 18)}" 
                    th:if="${par['parHole' + i] != null && !par['parHole' + i].isEmpty()}"
                    th:text="${par['parHole' + i]}"></td>
                <td>
                    <!-- 操作按钮区域 -->
                </td>
            </tr>
        </table>
    </div>
</div>

说明:

  • 用${#numbers.sequence(1,18)}生成1-18的数字序列
  • 通过par['parHole' + i]动态拼接字段名访问属性(需确保ParList类有对应getter方法)
  • 用th:if过滤空值字段,只渲染实际有数据的列

2. 动态生成新增球场表单(输入端)

通过下拉框选择洞数,结合JavaScript动态显示对应数量的输入框:

<form th:action="@{/discgolf/saveCourse}" th:object="${newCourse}" method="POST">
    <div class="form-group">
        <input type="text" th:field="*{name}" placeholder="Course name" class="form-control mb-4 col-4">
    </div>
    <!-- 洞数选择下拉框 -->
    <div class="form-group mb-4">
        <label>洞数:</label>
        <select id="holeCount" class="form-control col-2">
            <option value="9">9洞</option>
            <option value="14">14洞</option>
            <option value="18" selected>18洞</option>
        </select>
    </div>
    <!-- 动态输入框容器 -->
    <div id="parInputsContainer" class="container">
        <div id="parRow" class="row g-0">
            <div th:each="i : ${#numbers.sequence(1, 18)}" class="col mb-2">
                <label th:text="'#' + ${i}"></label>
                <input type="text" th:field="*{parLists[0]['parHole' + i]}" 
                       th:placeholder="${i}" class="form-control">
            </div>
        </div>
    </div>
    <button type="submit" class="btn btn-info col-2">Save Course</button>
</form>

<script>
    const holeCountSelect = document.getElementById('holeCount');
    const parInputs = document.querySelectorAll('#parRow .col');

    // 监听洞数选择变化,控制输入框显示
    holeCountSelect.addEventListener('change', function() {
        const count = parseInt(this.value);
        parInputs.forEach((input, index) => {
            input.style.display = index < count ? 'block' : 'none';
        });
    });

    // 初始化显示默认洞数
    holeCountSelect.dispatchEvent(new Event('change'));
</script>

说明:

  • 用*{parLists[0]['parHole' + i]}绑定到Course关联的第一个ParList对象的对应字段
  • JavaScript负责根据选择的洞数,显示/隐藏多余的输入框

三、关键注意事项

  • 若采用列表结构,Controller层需处理表单提交的列表数据绑定,可使用@ModelAttribute接收List<String>
  • 现有结构下,后端保存时需过滤空值的parHole字段,避免无效数据存入数据库
  • Thymeleaf的动态属性访问依赖公共getter方法,需确保ParList类中每个parHoleX都有对应的getter

内容的提问来源于stack exchange,提问作者Kayd Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 08:59:21