Thymeleaf,片段和默认参数

时间:2014-02-28 10:55:54

标签: java spring spring-mvc thymeleaf

我创建了fragment.html文件。它包含以下片段:

<div th:fragment="my_fragment(content)">
    <p th:text="${content}"></p>
</div>

我把上面的片段放到我的视图文件中:

<div th:replace="fragments :: my_fragment('test')"></div>

现在,我想将两个参数传递给my_fragment,但我必须确保向后兼容。

我尝试按如下方式解决问题:

<div th:fragment="my_fragment(content, defaultParameter='default value')">
    <p th:text="${content}"></p>
</div>

不幸的是,上述解决方案产生了错误:

  

org.springframework.web.util.NestedServletException:Request   处理失败;嵌套异常是   org.thymeleaf.exceptions.TemplateProcessingException:无法解析   分段。签名“my_fragment(content,defaultParameter ='default value')”   声明2个参数,但片段选择指定1个参数。   片段选择不正确匹配。

有什么想法吗?

5 个答案:

答案 0 :(得分:41)

Thymeleaf允许没有明确参数的片段签名:

<div th:fragment="my_fragment">
    <p th:text="${content}"></p>
    <p th:text="${defaultParameter}"></p>
</div>

要调用此片段并传递contentdefaultParameter,您可以按如下方式调用该片段:

<!-- both parameters not specified -->
<div th:replace="fragments :: my_fragment"></div>
<!-- only content parameter specified -->
<div th:replace="fragments :: my_fragment(content='a')"></div>
<!-- both parameters specified -->
<div th:replace="fragments :: my_fragment(content='a', defaultParameter='b')"></div>

但下面的内容不起作用:

<div th:replace="fragments :: my_fragment('a', 'b')"></div>

这条信息是自我表达的:

 Signature "my_fragment" declares no parameters, but fragment selection did specify parameters in a synthetic manner (without names), which is not correct due to the fact parameters cannot be assigned names unless signature specifies these names. 

因此,如果您希望保持向后兼容性,则应在调用片段时使用命名参数,并且不要在片段的签名中指定参数。

答案 1 :(得分:9)

允许片段的可选参数的最佳方法是使用&#34; th声明它们:with&#34;并用有意义的默认值描述它们。

因此,您可以在片段的声明标记中明确定义必需值和可选值。

这是一个简单的例子,有1个强制参数和2个可选参数:

<div th:fragment="printGreetings (name)" th:with="title=${title} ?: 'Mr.', greeting=${greeting} ?: 'Hello'">
    <span th:text="${greeting}">Hello</span>
    <span th:text="${title}">Mr.</span>
    <span th:text="${name}">John Doe</span>
</div>

然后您可以像下面这样调用它:

<div th:replace="fragments :: printGreetings (name='daniel')">
   Hello Mr. Daniel
</div>
<div th:replace="fragments :: printGreetings (name='Lea', title='Ms.')>
   Hello Ms. Lea
</div>
<div th:replace="fragments :: printGreetings (name='Lea', title='Ms.', 'Hi')>
   Hi Ms. Lea
</div>

(请注意,标签内的所有值都会被动态值替换。只是为了更好的阅读。)

答案 2 :(得分:5)

如果要提供默认值(如您的情况),可以使用elvis运算符指定默认值,例如:

<div th:fragment="my_fragment">
    <p th:text="${content}"></p>
    <p th:text="${defaultParameter ?: 'the backwards compat value'}"></p>
</div>

请参阅:elvis-operator

答案 3 :(得分:1)

对我来说最好的方法:

片段:

<div th:fragment="my_fragment(content)">
    <p th:text="${content}"></p>
</div>

如果内容来自模型:

<div th:replace="fragments :: my_fragment(${content})></div>

其他:

<div th:replace="fragments :: my_fragment('content')></div>

答案 4 :(得分:0)

最后我解决了这样的任务:

<div th:fragment="my_fragment2(content, param2)">
    <th:block th:replace="my_fragment(${content})"/>
</div>

<div th:fragment="my_fragment(content)" th:with="param2=${param2} ?: 'default value'">
    <p th:text="${content}"></p>
    <p th:text="${param2}"></p>
</div>

<div th:replace="fragments :: my_fragment2('test', 'my_value')"></div>

但这是开销:(

同时提出问题以发出Allow fragment parameters to have default values