Primefaces DataTable过滤器或分页器阻碍了顺序获取请求的呈现

时间:2016-04-13 14:57:44

标签: jsf primefaces filter datatable

我正在使用Primefaces DataTable组件。用户在点击按钮之前做出一些城市 - 地区服务类型选择,并且数据表充满了位于城市所需位置的所需城市服务(医院,学校等)。以下代码仅包含提取按钮和表格本身。

当您获取所需的第一个结果时,没有任何问题。一切都很好,paginator运作良好。按名称筛选结果时,问题开始。它们实际上也很好地过滤了,但是在完成过滤之后;如果您对城市,地区或服务做出其他选择并尝试取出它们;数据表的列填充了' | 0 | (空)| (空)|'行(我猜它是因为ID列是int类型而另外两个是字符串)。附加信息:新创建的空行数与前一个过滤结果完全相同。

我进行了必要的调试,发现在后端一切都很完美。我得到了所有获取的对象。实际上,当我在过滤条中键入任何内容时,新结果也会暴露出来。这似乎是客户端渲染中的一个问题,尽管我找不到解决它的方法。

非常感谢任何帮助。

更新:经过几个小时的工作后,我得出结论,原因可能不是过滤器而是分页器。因为当我关闭分页器并获得一个完整的可滚动表时,一切都运行良好。仍然不确定确切的原因,所以我根据这个编辑了问题主题。

p.s:我使用的是Primefaces 5.3,JSF 2.2 Mojarra,JDK 1.7,TomEE Plume

    <p:commandButton action="#{filterByLocation.fetchServicesByLocation}" id="elbuton" value="Fetch" icon="ui-icon-check" onclick="PF('servisWidget').clearFilters();" update="servisList" />

    <p:dataTable id="servisList" paginator="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" rows="10" var="loc" value="#{filterByLocation.finalResults}"
     widgetVar="servisWidget">
      <p:column headerText="ID">
        <h:outputText value="#{loc.id}" />
      </p:column>
      <p:column headerText="NAME" filterBy="#{loc.name}" filterFunction="#{filterByLocation.filterResults}">
        <h:outputText value="#{loc.name}" />
      </p:column>
      <p:column headerText="SERVICE NAME">
        <h:outputText value="#{loc.serviceName}" />
      </p:column>
    </p:dataTable>

我的支持豆(为清晰起见,排除了吸气剂/固定剂):

@ManagedBean
@ViewScoped
public class FilterByLocation {

    private List<LocationEntity> cities;
    private List<LocationEntity> districtSelection;
    private List<LocationEntity> finalResults = new ArrayList<LocationEntity>();
    private List<Integer> selectedNodes = new ArrayList<Integer>();

    private String filterText;
    private String filterName; 
    private int city;
    private int district;

    public FilterByLocation() {
        setCities(LocationTreeDAO.fetchCities());
    }

    public void listDistricts() {
        setDistrictSelection(LocationTreeDAO.fetchDistricts(city));
    }

    public void selectNode(NodeSelectEvent node) {
        TreeNode treeNode = node.getTreeNode();
        LayerEntity layer = (LayerEntity) treeNode.getData();
        selectedNodes.add(Integer.valueOf(layer.getId()));
    }

    public void unselectNode(NodeUnselectEvent node) {
        TreeNode treeNode = node.getTreeNode();
        LayerEntity layer = (LayerEntity) treeNode.getData();
        selectedNodes.remove(Integer.valueOf(layer.getId()));
    }

    public void fetchServicesByLocation() {
        setFinalResults(LocationTreeDAO.fetchFilteredServices(getCity(), getDistrict(), getSelectedNodes(), getFinalResults()));
        setFilterText("");
    }


    public boolean filterResults(Object value, Object filter, Locale locale) {

        setFilterText((filter == null) ? null : filter.toString().trim());
        if (filterText == null || filterText.equals("")) {
            return true;
        }
        if (value == null) {
            return false;
        }
        String searched = value.toString().toUpperCase();
        filterText = filterText.toUpperCase();

        if (searched.contains(filterText)) {
            return true;
        } else {
            return false;
        }


    }

描述情况的两个截图 before after

1 个答案:

答案 0 :(得分:0)

filterFunction参数 <p:column ... filterFunction="#{filterByLocation.filterResults}" ...>没有必要。

  1. 将声明更改为
  2. <p:column headerText="NAME" filterBy="#{loc.name}" filterMatchMode="contains">

    1. 为过滤后的值添加List
    2. <p:dataTable ... filteredValue="#{filterByLocation.filteredResults} ...>

      @ManagedBean
      @ViewScoped
      public class FilterByLocation {
          ...
          private List<LocationEntity> filteredResults;
          ...
      }