Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring th:each或如何正确恢复复选框列表中未设置复选框的Thymeleaf-Checked属性,其中一些复选框以前已选中_Spring_Checkbox_Radio Button_Thymeleaf_Checked - Fatal编程技术网

Spring th:each或如何正确恢复复选框列表中未设置复选框的Thymeleaf-Checked属性,其中一些复选框以前已选中

Spring th:each或如何正确恢复复选框列表中未设置复选框的Thymeleaf-Checked属性,其中一些复选框以前已选中,spring,checkbox,radio-button,thymeleaf,checked,Spring,Checkbox,Radio Button,Thymeleaf,Checked,在我的应用程序中,我想创建一个新的风险(风险对象的实例),创建时,我想显示5个复选框和三个单选按钮。所选选项特定于风险对象的每个实例 稍后,我想显示所有新增风险的列表,每个风险上都有一个编辑选项按钮。我希望我的应用程序还原特定于所选风险的视图(当单击所选风险上的编辑按钮时)-风险名称、所有复选框和单选按钮均按先前选择的方式选中。我希望能够再次编辑这些复选框选择,以便所有新的更改都能正确地反映在MySQL中 作为Thymeleaf的新手,我做了以下几点: <div th:each="top

在我的应用程序中,我想创建一个新的风险(风险对象的实例),创建时,我想显示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>
    model.addAttribute("topics", topicsService.findAll());
    model.addAttribute("types", typesService.findAll());

有点不对劲!
我确信控制器和Hibernate/MySQL部分工作正常(我使用日志进行了检查)

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

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


怎么了?

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

“…th:field将处理该问题,并将checked=“checked”属性添加到相应的输入标记中。”

我还发现了以下指南:

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

我不想重复上面提到的Thymeleaf论坛页面中已经出现的内容(详情请参见管理员的第一个回复/解释-论坛线程中的第二个)-只想做一个小总结并强调几点:

  • 使用th:each时确实不需要添加“checked”

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

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

    model.addAttribute("topics", Topics.values());
    model.addAttribute("types", Types.values());
    
(如果需要动态的,请执行以下操作:

<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>
    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:Thymeleaf返回的所有选项数组现在应该能够在第一个数组中的值与第二个数组中的值匹配时将复选框/单选按钮标记为选中

由于对于单选按钮,您只能选择一个选项th:field=“*{type}”实际上不返回数组-它只返回一个项目。但对于复选框,它应该是数组-因此Risk.java中的“topic”字段必须返回数组

为此,我们需要一个转换器-一个名为StringListConverter的类,它实现AttributeConverter

(我在这里学会了如何做到这一点。如果不是在www.stackoverflow.com上找到这个答案,我将无法最终开发这个应用程序,也不会写下所有这些: )

然后,在您的表单backing model class-Risk.java中,在我的例子中,您需要执行以下操作:

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

private String type;
@Convert(converter=StringListConverter.class)
私有列表主题=新建ArrayList();
私有字符串类型;
类型可以是一个字符串

就是这样

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

我在这里发布了一个相关问题-

此外,我还想对所有风险项目使用不同的颜色,在我的风险列表中使用偶数序列号-它位于index.html中

请参阅下面使用链接的完整示例代码)

指向我的GitHub回购的链接:

  • 带有静态复选框集的示例:

  • 动态生成复选框的示例:


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

"?