【问题标题】:Thymeleaf - Checked attribute of checkbox is not set in th:each OR how to properly restore a list of checkboxes some of which were previously checkedThymeleaf - 未在 th:each 中设置复选框的选中属性,或者如何正确恢复之前选中的复选框列表
【发布时间】:2018-04-06 04:38:32
【问题描述】:

在我的应用程序中,我想创建一个新的风险(风险对象的一个​​实例),当它创建时,我想显示 5 个复选框和三个单选按钮。选定的选项特定于风险对象的每个实例。

稍后我想显示所有已添加风险的列表,每个风险上都有一个编辑选项按钮。我希望我的应用程序恢复特定于选定风险的视图(当单击选定风险上的编辑按钮时) - 使用风险名称,所有复选框和单选按钮都已选中,如先前选择的那样。我希望能够再次编辑这些复选框选择,以便所有新更改都正确反映在 MySQL 中。

作为 Thymeleaf 的新手,我做了以下工作:

<div th:each="top : ${topic}">
    <input type="checkbox" th:field="*{topic}" th:checked="${top.checked}" th:value="${top.name}"/><label th:text="${top.name}">Something is wrong !</label>
</div>

我确信 Controller 和 Hibernate/MySQL 部分工作正常(我使用 Logs 进行了检查)。

这很好用——但前提是我只选择了一个复选框(最初是在我添加风险时)。

如果我选择了多个复选框(添加风险时),然后选择此风险进行编辑,则不会选中任何复选框。

怎么了?

【问题讨论】:

    标签: spring checkbox radio-button thymeleaf checked


    【解决方案1】:

    经过一番研究,我在 Thymeleaf 的文档中发现了以下文字:

    “... th:field 会处理这个问题,并会在相应的输入标签中添加一个 checked="checked" 属性。”。

    我也找到了这个指南:

    http://forum.thymeleaf.org/The-checked-attribute-of-the-checkbox-is-not-set-in-th-each-td3043675.html

    然后我设法开发了几个小应用程序,我想分享我的发现并希望它对某人有所帮助。 (可能对有经验的人来说太详细了,但我希望大家都清楚)

    我不想重复上述 Thymeleaf 论坛页面中已有的内容(详见管理员的第一个回复/解释 - 论坛帖子中的第二个) - 只想做一个小总结并强调几点:

    • 在使用th:each的时候确实不需要加‘checked’;

    • 您必须添加 th:field=“{...}” ,它应该具有模型类中字段的名称(Thymeleaf 称为 form-b​​acking bean - th:object )到哪个复选框有关系。更多信息:我在上面说过我的“表单支持 bean”是 Risk.java。对于每个风险对象实例,选中的复选框代表特定于该风险实例的主题。并将选定的主题分配给 Risk.java 实例的字段“主题”(因此在保存实例时在 MySQL 的相关表中)。在我的例子中,该字段的名称应该在 th:field=“{...}” 中作为 th:field=“*{topic}”。当您选中复选框时,Thymeleaf 将使用其 setTopic 方法将选定的值保存到 Risk.java 的主题字段中,并且当它需要恢复视图时,Thymeleaf 将使用 Risk.getTopic 方法来获取有关先前选定项目的信息。

    • 复选框(或单选按钮)的所有值都应该来自另一个来源 - 如果您需要一组静态复选框,或者如果您需要动态生成复选框,您可以使用一个类(我需要静态我的应用程序的一组复选框,但我决定尝试创建一个动态的复选框 - 请参阅下面我的 Github 存储库的链接以查看我设法开发的代码)。因此,对于我的应用程序,我创建了一个枚举主题,其中包含复选框的所有值和枚举类型,其中包含单选按钮的所有值。然后在你的控制器类中,你应该将所有值添加到模型的属性中——我这样做是因为我使用了一个枚举:

      model.addAttribute("topics", Topics.values());
      model.addAttribute("types", Types.values());
      

    (如果您需要动态的,请执行以下操作:

        model.addAttribute("topics", topicsService.findAll());
        model.addAttribute("types", typesService.findAll());
    

    )

    那么你应该有类似的东西:

        <div>
                <div th:each="top : ${topics}">
                    <input type="checkbox" th:field="*{topic}"  th:value="${top.id}"/><label th:text=" | &nbsp; ${top.name}|">Something is wrong !</label>
                </div>
        </div>
    
        <div>
                <div th:each="typ : ${types}">
                    <input type="radio" th:field="*{type}"  th:value="${typ.id}"/><label th:text="| &nbsp; ${typ.name} |">Something is wrong !</label>
                </div>
        </div>
    

    地点:

    • 如前所述,th:field="{topic}" 对应于表单支持模型类 - Risk.java 的字段。th:field="{type}" 相同;

    • th:each="top : ${topics}" 中的主题应与您在控制器中提供的属性名称匹配。

    最重要的部分是 th:field="*{topic}" 应该返回一个数组。

    th:field=“*{topic}” 返回一个选定项目数组和 th:each 返回所有选项数组 Thymeleaf 现在应该能够在第一个数组中的值与第二个数组中的值匹配时将复选框/单选按钮标记为选中数组。

    因为在单选按钮的情况下,您只能选择一个选项 th:field=“*{type}” 实际上并没有返回一个数组 - 它只返回一个项目。但如果是复选框,它应该是一个数组 - 因此 Risk.java 中的“主题”字段必须返回一个数组。

    为此,我们需要一个转换器——一个名为例如的类。实现 AttributeConverter 的 StringListConverter….

    (我在这里学到了如何做到这一点。如果不是 www.stackoverflow.com 中的这个答案,我将无法最终确定这个应用程序,也不会写下所有这些: https://stackoverflow.com/a/34061723/6332774)

    然后在您的表单支持模型类中 - 在我的情况下为 Risk.java 您需要执行以下操作:

    @Convert(converter = StringListConverter.class)
    private List<String> topic = new ArrayList<>();
    
    private String type;
    

    类型可以简单地是一个字符串。

    就是这样。

    (我想以表格形式显示复选框,指示所需的列数 - 我可以做到,但我不确定它有多干净或有多安全。相关代码在下面链接的示例项目中的 riskformtable.html 中.

    我在这里发布了一个相关问题 - Thymeleaf - Displaying checkboxes in table form when using th:each - is what I am doing safe?

    我还想为我的风险列表中具有偶数序号的所有风险项目使用不同的颜色 - 它在 index.html 中

    使用下面的链接查看完整的示例代码)

    指向我的 GitHub 存储库的链接:

    【讨论】:

    • 谢谢。已经坚持了几个小时
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 2022-01-21
    • 2019-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多