【问题标题】:JSF: rich datatable filtering, dynamic columns, and passing argumentsJSF:丰富的数据表过滤、动态列和传递参数
【发布时间】:2013-07-01 10:09:52
【问题描述】:

我正在处理 JSF 页面上的 rich:datatable。该表可以变得非常大,并使用 rich:datascroller 进行分页。大多数列都是硬连线的,并且将始终存在,但是还有一些基于附加值的可选列,这些附加值需要为每个潜在的附加值生成。我已经能够很容易地做到这一点。但是,我遇到了过滤问题。

我在每一列上都使用了一个过滤器。它与列标签和排序功能一起放置在标题中。每一列都可以正常工作,但是由于 filtermethod 默认的工作方式,我在过滤方面遇到了障碍。这是一个简单的例子:

<rich:datatable id="thetable" value=#{backingBean.stuff} var="b">
<!-- First column, standard filter method, works just fine -->
    <rich:column sortBy="#{b.field1}" filterMethod="#{filterBean.filterField1}">
        <f:facet name="header">
            <ui:fragment>
                <h:outputText value="Field 1" />
                <h:inputText value="#{filterBean.filterMap['Field1']}" />
            </ui:fragment>
        </f:facet>
        #{b.field1}
    </rich:column>
<c:forEach items="#{backingBean.extraStuff}" var="e">
    <rich:column sortBy="#{b.getExtra(e)}" filterMethod="???">
        <f:facet name="header">
            <ui:fragment>
                <h:outputText value="#{b.getExtra(e).description}" />
                <h:inputText value="#{filterBean.filterMap['b.getExtra(e).code']}" />
            </ui:fragment>
        </f:facet>
        #{b.getExtra(e).description}
    </rich:column>
</rich:datatable>

???将很快介绍。至于滤豆:

public class FilterBean {

    public Map<String, String> filterMap = new HashMap<String, String>();

    public boolean filterField1(Object current){
        return ((BackingBean) current).contains(filterMap.get("Field1"));
    }
}

这很简单。过滤器 inputText 绑定到 hashMap 中的预设字符串,该字符串在方法中检索并用于过滤,因此我不需要为每个过滤器设置单独的字段。这很好用,但我仍然需要为每个过滤器使用单独的方法,这将我带到 ???在 JSF 代码中...

我想做的是将参数传递给过滤器方法以说明动态列。事实上,我想用一个过滤器方法简化整个类,并将映射的字符串与来自当前对象的字段一起传入。但是,这是行不通的。我试过了:

filterMethod="#{filterBean.filterStuff(b, 'Field1')}" 

但我最终得到了过滤器字符串,但当前对象为空。我不确定发生了什么事。如果我正确阅读了项目中的依赖项,我使用的是一些相当旧的 EL、JSF、JSP 等版本,我真的无法改变它。不过,这个项目确实使用了 Seam,而且我之前在这个项目中已经在 EL 中成功地传递了参数。仅仅是 EL 2.2 支持传递对象,而旧版本只支持原语和字符串吗?有什么方法可以让我做到这一点,还是我没有从头开始构建大量额外的东西就被困住了?

好的,Seam 似乎可以做到这一点,但它不喜欢迭代变量。如果我从支持 bean 引用 List 中的索引,我可以传递该对象,但这无济于事,因为我无法告诉它搜索每一行...

【问题讨论】:

    标签: java jsf filter richfaces el


    【解决方案1】:

    我的用例有点不同,但基本上我遇到了同样的问题并找到了可行的解决方案。

    用例:我有几个 XHTML 文件及其支持 bean,它们都提供了一个包含不同类型实体列表的表格。在此表中,实体的某些属性有几列可以过滤。由于内置过滤器只进行“开始于”搜索,而我需要更高级的过滤器,因此我必须使用filterMethod。 但是我不想用数百个完全相同的简单过滤器方法(仅具有不同的属性)弄乱我的支持bean。所以我一直在寻找一种更通用的方法——这就是我的方法:

    在后端,我创建了一个名为FilterMethodWrapper 的新类(为了便于理解,我将其作为嵌套静态类在这里)和一个访问它的方法:

    import org.apache.commons.beanutils.PropertyUtils;
    
    public class BackendBean 
    {
       private String[] filterValues; 
       // initialize filterValues somewhere, add getter and setter
    
        public static class FilterMethodWrapper 
        {
            private final String fieldName;
            private final String filterValue;
    
            public FilterMethodWrapper(final String fieldName, String filterValue)
            {
                this.fieldName = fieldName;
                this.filterValue = filterValue;
            }
    
            public boolean doFilter(Object current) throws ...
            {
                final String stringValue = (String) PropertyUtils.getSimpleProperty(current, fieldName);
                // compare stringValue and filterValue somehow (e.g. contains)
                // and return result
            }
        }
    
        public FilterMethodWrapper getFilterMethodWrapper(String fieldName, int filterValueIndex)
        {
            return new FilterMethodWrapper(fieldName, getFilterValues()[filterValueIndex]);
        }
    }
    

    在 XHTML 中按如下方式使用它:

    <rich:column filterMethod="#{backendBean.getFilterMethodWrapper('username', 0).doFilter}" filterEvent="onkeyup" >
      <f:facet name="header">
        <h:panelGrid style="display:inline;">
          <h:outputText value="Username"/>
          <h:inputText value="#{backendBean.filterValues[0]}" />
        </h:panelGrid>
      </f:facet>
      <h:outputText value="#{_item.username}" />
    </rich:column>
    

    编辑:我正在使用 JSF 1.2 和 RichFaces 3.3.3.Final

    Edit2:除了编写 FilterMethodWrapper,您还可以使用一些 Predicate-implementation 并在前端使用 apply-method(或者您根据此提案编写自己的 Predicate-implementation,它比此 FilterMethodWrapper 更可重用)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 2011-07-18
      • 2015-11-30
      • 2011-08-19
      • 2013-06-28
      相关资源
      最近更新 更多