百里香叶、碎片和默认参数

2022-08-31 22:21:32

我已经创建了片段.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 processing failed;嵌套异常是 org.thymeleaf.exceptions.TemplateProcessingException: 无法解析片段。签名“my_fragment(content,defaultParameter='default value')”声明 2 个参数,但片段选择指定 1 个参数。片段选择不匹配。

有什么想法吗?


答案 1

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. 

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


答案 2

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

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

下面是一个简单的示例,其中包含 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.', greeting='Hi')>
   Hi Ms. Lea
</div>

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


推荐