【问题标题】:JSF conditional converterJSF 条件转换器
【发布时间】:2018-12-24 23:15:25
【问题描述】:

我创建了一个非常通用的 jsf 复合组件,它从通用行数据呈现一个 primefaces 数据表。

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

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

所以我用一个converterId 扩展了ColumnDescription。 问题是我只需要将转换器附加到 ColumnDescription 中的 converterId 不为空。

第一个想法:

<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

有条件加转换器吗?

提前致谢 塞巴斯蒂安

【问题讨论】:

  • 正如例外所说,JSF 转换器用于将 Java 值转换为 HTML 值,反之亦然。它们总是用于输入组件(选择列表、选择菜单......)。将其附加到列的目的是什么?也许您正在寻找类似值格式化程序的东西?
  • 你试过&lt;f:converter converterId="#{column.converterId}" rendered="#{column.hasConverter}"/&gt;吗?
  • @JasperdeVries 是的,这是我的第一个想法,但转换器没有渲染属性
  • 尝试在h:outputText 中添加&lt;f:attribute name="converter" value="#{column.converterId}" rendered="{column.hasConverter}" /&gt;
  • @Kukeltje 没用。属性标签中没有呈现属性。但即使没有这个属性

标签: jsf jsf-2 jsf-2.2


【解决方案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?。因此,在/WEB-INF/ 中创建一个名为my.taglib.xml 的文件:

<?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”。

【讨论】:

    猜你喜欢
    • 2012-12-26
    • 1970-01-01
    • 2011-11-29
    • 2013-04-30
    • 2011-01-06
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多