JSF条件转换器

时间:2018-07-17 09:47:32

标签: jsf jsf-2 jsf-2.2

我创建了一个非常通用的jsf复合组件,该组件从通用行数据中渲染了一张primefaces dataTable。

对于应该渲染的每一行,我都有一个名为ColumnDescription的pojo,其中包含标题名称和用于获取数据的行数据索引。

这很好,但是现在我要求允许在列上设置可选转换器。

因此,我用converterId扩展​​了ColumnDescription。 问题是,如果ColumnDescription中的converterId不为null,则只需将转换器附加到。

第一个想法:

<h:outputText value="#{row[column.rowBeanProperty]}">
<c:if test="#{column.hasConverter}">
    <f:converter converterId="#{column.converterId}" />
</c:if>

这不起作用。 if标记中的测试甚至不会进行评估。 我认为这是因为将对jsp标签的不同阶段进行评估。

第二个想法 将呈现的属性用于条件

<h:outputText value="#{row[column.rowBeanProperty]}">
<ui:fragment rendered="#{column.hasConverter}">
    <f:converter converterId="#{column.converterId}" />
</ui:fragment>

这不起作用,因为转换器需要附加到可编辑的值组件上

TagException: /components/dataReport.xhtml @38,80 <f:converter> Parent not an instance of ValueHolder: com.sun.faces.facelets.tag.ui.ComponentRef@35b683c2

有没有机会有条件地添加转换器?

预先感谢 塞巴斯蒂安

1 个答案:

答案 0 :(得分:1)

您可以做的是编写自己的转换器。参见How create a custom converter in JSF 2?。如果您知道可以通过调用context.getApplication().createConverter(converterId)来获得转换器,那将非常简单:

@FacesConverter("optionalConverter")
public class OptionalConverter implements Converter {

  private String converterId;

  private boolean disabled;

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    return disabled
           ? value
           : context.getApplication().createConverter(converterId).getAsObject(context, component, value);
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value == null) {
      return null;
    }
    return disabled
           ? value.toString()
           : context.getApplication().createConverter(converterId).getAsString(context, component, value);
  }

  // Getters and setters
}

然后为该转换器创建一个标签。参见How to create a custom Facelets tag?。因此,请在my.taglib.xml中创建一个名为/WEB-INF/的文件:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
                version="2.0">
  <namespace>http://my.com/jsf/facelets</namespace>

  <tag>
    <tag-name>optionalConverter</tag-name>
    <converter>
      <converter-id>optionalConverter</converter-id>
    </converter>
    <attribute>
      <name>converterId</name>
      <required>true</required>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>disabled</name>
      <required>false</required>
      <type>boolean</type>
    </attribute>
  </tag>

</facelet-taglib>

并将其添加到web.xml

<context-param>
  <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
  <param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>

经过测试:

Enabled:
<h:outputText value="1234">
  <my:optionalConverter converterId="javax.faces.Number" />
</h:outputText>
Disabled:
<h:outputText value="1234">
  <my:optionalConverter converterId="javax.faces.Number" disabled="true" />
</h:outputText>

输出:“启用:1,234禁用:1234”。