在PrimeFaces 5.0 final中的数据表过滤器中使用转换器

Tin*_*iny 1 jsf primefaces jsf-2.2

给出以下XHTML代码(关于PrimeFaces 5.0 final).此处可以看到对数据表过滤器的新更改.

<p:dataTable id="dataTable" var="row" value="#{testManagedBean}"
             lazy="true"
             rowKey="#{row.transporterId}"
             widgetVar="dataTableUIWidget">

    <p:column id="id" headerText="Id" sortBy="#{row.transporterId}">
        <h:outputText value="#{row.transporterId}"/>
    </p:column>

    <p:column id="transporter" headerText="Transporter" filterBy="#{row.transporterName}">
        <f:facet name="filter">
            <p:inputText onkeyup="PF('dataTableUIWidget').filter();"/>
        </f:facet>
        <h:outputText value="#{row.transporterName}"/>
    </p:column>
</p:dataTable>
Run Code Online (Sandbox Code Playgroud)

以下是面向转换器以修剪字符串中的前导和尾随空格.

@FacesConverter(forClass=String.class)
public final class StringTrimmer implements Converter
{
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return value != null ? value.trim() : null;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return (String) value;
    }
}
Run Code Online (Sandbox Code Playgroud)

此转换器是否可以全局应用于数据表中指定的所有类型字符串过滤器(包括已应用的其他UI组件)?

<f:facet name="filter">
    <p:inputText onkeyup="PF('dataTableUIWidget').filter();"/>
</f:facet>
Run Code Online (Sandbox Code Playgroud)

或者我必须修改转换器类以获得注释,

@ManagedBean
@RequestScoped
public final class StringTrimmer implements Converter
{
    //...
}
Run Code Online (Sandbox Code Playgroud)

然后手动将此转换器应用于所有相关过滤器,如此

<f:facet name="filter">
    <p:inputText onkeyup="PF('dataTableUIWidget').filter();" converter="#{stringTrimmer}"/>
</f:facet>
Run Code Online (Sandbox Code Playgroud)

这个转换器能否以某种方式全局应用,以便我们不需要converter="#{stringTrimmer}"为所有字符串类型过滤器明确指定?

这个问题应该与JSF而不是PrimeFaces更相关.

Bal*_*usC 6

这是因为UIInput#getValue()默认值Object不是String.只要您没有将基于组件的value属性显式绑定UIInput到更具体类型的支持bean属性,例如String,就不会查找特定的转换器.

如果你改变它应该工作

<p:inputText onkeyup="PF('dataTableUIWidget').filter();"/>
Run Code Online (Sandbox Code Playgroud)

例如

<p:inputText value="#{bean.filter}" onkeyup="PF('dataTableUIWidget').filter();"/>
Run Code Online (Sandbox Code Playgroud)

有一个private String filter属性(和一个getter + setter).但如果您不在模型中的任何其他位置使用此属性,那么这确实很混乱.

替代方案确实是通过converter属性明确声明转换器.根据@FacesConverter合同,不可能在同一转换器类上同时声明转换器ID和转换器类似

@FacesConverter(value="stringTrimmer", forClass=String.class)
public final class StringTrimmer implements Converter {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

只会注册转换器ID,并且会在服务器日志中显示警告.

警告:@FacesConverter同时使用value和forClass,仅应用值.

但是,它可能有两个 @ManagedBean,并@FacesConverter在同一类.您应该只了解它们彼此不合作并且将创建完全独立的实例.但是如果转换器被设计为无状态(即所有状态都保存在方法块中并且类没有任何实例变量/依赖性),这不应该受到伤害.

@ManagedBean
@ApplicationScoped
@FacesConverter(forClass=String.class)
public final class StringTrimmer implements Converter {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以继续获益,forClass并且仍然可以通过#{stringTrimmer}那些forClass无法应用的组件将转换器作为托管bean引用.

<p:inputText onkeyup="PF('dataTableUIWidget').filter();" converter="#{stringTrimmer}" />
Run Code Online (Sandbox Code Playgroud)