提问者:小点点

使用百里香叶泉创建自定义标签(就像JSP一样)


我正在尝试使用Thymeleaf创建自定义标签,就像在JSP中一样。我现在拥有的标签是:

<select th:include="fragments/combobox :: combobox_beans (beans=${@accountService.getAccounts()}, innerHTML='id,description,currency', separator=' - ', dumbHtmlName='List of accounts', name='sender' )" th:remove="tag"></select>

其目的只是定义bean列表、要在屏幕上显示的bean的财产、它们之间的分隔符、显示为本机模板时的默认值,以及我们在此处理的原始bean的属性名称。

组合框.html:

<div th:fragment="combobox_beans (beans, innerHTML, separator, dumbHtmlName, name)">
<select th:field="*{__${name}__}" class="combobox form-control" required="required">
    <option th:each="obj : ${beans}" th:with="valueAsString=${#strings.replace( 'obj.' + innerHTML, ',', '+''  __${separator}__ ''+ obj.')}"
        th:value="${obj}" th:text="${valueAsString}" >            
        <p th:text="${dumbHtmlName}" th:remove="tag"></p>
    </option>
</select>

我需要选项标签的文本基于片段的innerHTML属性(innerHTML='id,description,devise ')中设置的属性。我对这段文字有一个选择:

<option value="...">obj.id+' - '+ obj.description+' - '+ obj.currency</option>

而不是预期的结果

<option value="...">2 - primary - USD</option>

我知道这是由于使用了字符串库,它会产生一个字符串。有没有办法让百里香叶重新评估这个字符串,再次被理解为一个对象?

也许在这种情况下使用字符串库是错误的。。。也许我需要使用th:each来将每个bean作为一个对象进行处理并读取其财产,但同样,如何仅获取innerHtml中指定的财产

任何人都有解决方案或解决方案
谢谢。


共1个答案

匿名用户

如果有一种方法可以让你在百里香叶/Spring的表达中做你想做的事情,它肯定非常复杂和冗长,而且读起来可能会很痛苦。

更简单的方法是在表达式上下文中添加一个定制的工具对象。只需要很少的代码。这个回答就说明了。

然后您需要将新的方言作为附加方言添加到Spring xml配置中的模板引擎中。假设您有一个相当标准的Spring配置,它应该类似于此。

<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
  <property name="templateResolver" ref="templateResolver" />
  <property name="additionalDialects">
    <set>
      <bean class="mypackage.MyUtilityDialect" />
    </set>
  </property>
</bean>

现在对于实用程序对象

您想要的是按名称从对象中获取属性,并用分隔符将它们的值组合起来。似乎属性名称的列表可以是任意大小的。对于通过名称访问属性,最方便的方法是使用像Apache beanutils这样的库。

您的自定义实用程序对象使用 Java 8 流库、lambda 和 Beanutils 可能如下所示:

public class MyUtil {

  public String joinProperties(Object obj, List<String> props, String separator){
    return props.stream()
          .map(p -> PropertyUtils.getProperty(obj,p).toString())
          .collect(Collectors.joining(separator))
  }
}

然后,当您将方言添加到SpringTemplateEngine时,您可以调用您的实用程序:

th:with="valueAsString=${#myutils.joinProperties(obj,properties,separator)}"

我已经用列表的属性替换了你的 innerHTML 参数

然后,您的调用标签应如下所示。

<select th:include="fragments/combobox :: combobox_beans (beans=${@accountService.getAccounts()}, properties=${ {'id','description','currency'} }, separator=' - ', dumbHtmlName='List of accounts', name='sender' )" th:remove="tag"></select>