我创建了一个非常通用的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
有没有机会有条件地添加转换器?
预先感谢 塞巴斯蒂安
答案 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”。