Thymeleaf#lists.contains()表达式实用程序不起作用

时间:2013-12-18 19:20:25

标签: java expression thymeleaf

我正在使用百里香标准方言并尝试在表单中呈现复选框列表。渲染是可以的,但问题是我尝试使用thymeleaf#lists.contains()表达式实用程序方法将“checked”属性应用于复选框。

所以我有一个包含以下字段的模型类:

private List<Template> templates;

@FormParam("selectedTemplates")
private List<String> selectedTemplates = Lists.newArrayList();

Thymeleaf模板html片段:

<div th:each="template : *{templates}">
    <input type="checkbox" name="selectedTemplates" th:value="${template.id}" 
    th:checked="${#lists.contains(product.selectedTemplates, template.id)}" />
    <label th:text="${template.filename} + ' (' + ${template.description} + ')'" />
    <!-- Attempt to use the list contains to check the field -->
    <div th:text="${product.selectedTemplates}"/>
    <div th:text="${template.id}"/>  
    <div th:text="${#lists.contains(product.selectedTemplates, template.id)}" />
</div>

页面上应该选中的复选框之一的输出。

<input type="checkbox" name="selectedTemplates" value="4" /> (Template Name)
<div>[4,5]</div>
<div>4</div>
<div>false<div>

正如您所看到的,我打印了具有值[4,5]的列表,并使用#lists.contains方法查看它是否包含template.id,但是,该方法始终返回false。我甚至尝试了一些硬编码的id来测试方法,我总是得到“假”回来。

例如:

<div th:text="${product.selectedTemplates}"/>
<div th:text="${#lists.contains(product.selectedTemplates, 4)}" />

打印[4,5]错误

<div th:text="${product.selectedTemplates}"/>
<div th:text="${#lists.contains(product.selectedTemplates, '4')}" />

打印[4,5]错误

不确定我做错了什么,但它似乎很直接,不知道还有什么可以尝试。我的猜测是语法有问题。非常感谢任何建议或意见。我无法找到解决这个问题的任何资源,百日咳指南会迅速掩盖该部分。

4 个答案:

答案 0 :(得分:16)

我在百里香论坛上提出了这个答案并得到了一些帮助来确定根本原因和解决方案。见[http://forum.thymeleaf.org/Problem-with-thymeleaf-expression-utility-lists-contains-td4027317.html][1]

基本上,单个字符串默认被解释为字符类型,因此永远不会匹配列表中的任何字符串。多字符字符串计算为字符串类型因此按预期工作。通过在html编码引号中封装要搜索的值,解析器被强制将单个字符串评估为字符串类型而不是char类型。例如:

<div th:text="${#lists.contains(testList, &quot;3&quot;)}"/>
<div th:text="${#lists.contains(testList, &quot;P&quot;)}"/>

只是想发布这个以防任何人对根本原因和解决方案感兴趣。

答案 1 :(得分:5)

我知道这个问题已经过时了,但我发布了这个答案,这对其他有相同问题的用户非常有用。

我不知道是你还是其他用户,但here我发现我们必须添加

  

''+ template.id

这样:

th:checked="${#lists.contains(product.selectedTemplates, '' + template.id)}" 

对我来说它有效!谢谢

答案 2 :(得分:2)

我做了一些进一步的实验,发现#lists.contains()实用程序方法不适用于单个字符串的问题。我想补充说我使用的是thymeleaf 2.0.19,但也尝试了2.1.1.RELEASE,结果相同。

我在模型中创建了一个简单的列表并添加了一些值:

@FormParam("testList") 
private List<String> testList = Lists.newArrayList(); 

testList.add("test1"); 
testList.add("test2"); 
testList.add("3"); 
testList.add("P"); 
testList.add("33");

然后测试#lists.contains()方法,如下所示:

<div th:text="${product.testList}"/>
<div th:text="${#lists.contains(product.testList, 'test1')}"/>
<div th:text="${#lists.contains(product.testList, 'test2')}"/>
<div th:text="${#lists.contains(product.testList, '3')}"/>
<div th:text="${#lists.contains(product.testList, 'P')}"/>
<div th:text="${#lists.contains(product.testList, '33')}"/>

输出如下:

<div>[test1, test2, 3, P, 33]</div>
<div>true</div>
<div>true</div>
<div>false</div>
<div>false</div>
<div>true</div>

因此,显然该方法不适用于单个字符串。因为我正在开发一个新项目,所以我只需重置驱动这些ID的序列,这样我就没有任何单个字符ID可供使用。这当然不是我希望的解决方案,但它有效。我还要补充一点,为了让方法在我的问题的上下文中工作,我必须像我这样在我的id中添加一个空字符:

th:checked="${#lists.contains(product.selectedTemplates, '' + template.id)}"

没有它,contains方法将返回“false”,因为template.id是Long类型。

答案 3 :(得分:0)

正如我所看到的,您选择的模板包含模板列表而不是ID,对吧?

如果是这种情况,你应该检查这样的清单:

<input type="checkbox" name="selectedTemplates" th:value="${template.id}" th:checked="${#lists.contains(product.selectedTemplates, template)}" />