【问题标题】:Sorting in an dynamically filled Datatable with lazy loading使用延迟加载对动态填充的数据表进行排序
【发布时间】:2019-01-27 07:18:29
【问题描述】:

我的延迟加载数据表有问题。 首先,这里是代码:

 <p:tabView>
    <!-- Tabs A and B, working fine -->
    <p:tab title="C">       
        <p:commandButton value="get C" id="openC" actionListener="#{backingBean.initC}" render="cTable" update="cTable"></p:commandButton>
        <p:separator/>
        <p:dataTable id="cTable" var="cTable" value="#{backingBean.lazyC}" paginator="true" 
            paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
            rowsPerPageTemplate="5,10,15" rows="10" sortMode="multiple" lazy="true" rendered="#{backingBean.cAvailable}">
            <c:forEach var="colC" items="#{backingBean.headerAllocationC}"> 
                <p:column headerText="#{colC.header}" sortBy="#{cTable[colC.property]}">
                    <div align="center">
                        <h:outputText value="#{cTable[colC.property]}"></h:outputText>
                    </div>
                </p:column>
            </c:forEach>
        </p:dataTable>
    </p:tab>
</p:tabView>

按照我的惰性数据模型的排序方法:

@Override
public List<cBean> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String,Object> filters){
    List<cBean> data = new ArrayList<cBean>();
    if (multiSortMeta != null) {
        for (SortMeta sortMeta : multiSortMeta) {
            System.out.println("SORTFIELD:" +sortMeta.getSortField());
            System.out.println("SORTORDER:" +sortMeta.getSortOrder());
            //System.out.println("SORTFUNCTION:"+sortMeta.getSortFunction());
            System.out.println("COLUMN:" +sortMeta.getColumn());
            System.out.println("CLASS:" +sortMeta.getClass());
        }
    }
    for (cBean c : datasource) {
        boolean match = true;
        if (filters != null) {
            for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                try {
                    String filterProperty = it.next();
                    Object filterValue = filters.get(filterProperty);
                    String fieldValue = String.valueOf(c.getClass().getField(filterProperty).get(c));
                    if (filterValue == null || fieldValue.startsWith(filterValue.toString())) {
                        match = true;
                    }
                    else {
                        match = false;
                        continue;
                    }
                } catch (Exception e) {
                    match = false;
                }
            }
        }
        if (match) {
            data.add(c);
        }
    }
    int dataSize = data.size();
    this.setRowCount(dataSize);
    if (dataSize > pageSize) {
        try {
            return data.subList(first, first+pageSize);
        } catch (IndexOutOfBoundsException e) {
            return data.subList(first, first+(dataSize%pageSize));
        }
    } else {
        return data;
    }
}

我的问题: 数据表被渲染,并显示数据它应该如何做。 现在我想根据一(或多)列对表格进行排序。加载方法被调用,但传递给我的加载方法的排序字段字符串是错误的(准确地说:“属性]”被打印)。

据我了解,我的语法不应该是错误的,正如我所说,数据的显示是完全正确的。 (所以语法适用于 outputTexts,但不适用于我在 p:column 中的 sortBy 子句?!)

我的 primefaces-components 语法有问题吗? 为什么只交了财产,而不是完整的字符串? (如果移交的是 cTable[colC.property],我会以某种方式理解这种情况,但由于它只是字符串的后半部分,老实说,我完全一无所知。

如果可以为我解决问题并在最好的情况下提供解决方法,那就太好了:)

【问题讨论】:

  • 到目前为止我从未使用过动态列,但我担心使用c:forEach 可能不是正确的选择,您是否尝试过使用p:columns,如showcase 所示?跨度>
  • 这应该有助于解释原因:stackoverflow.com/questions/29021036/…

标签: sorting jsf primefaces datatable lazy-loading


【解决方案1】:

好的,所以我已经开始工作了。 似乎 forEach 确实是这里造成麻烦的原因。感谢您将我带入正确的轨道@perissf

最后一件有趣的事情是为什么它只交出了一部分表达式,但是很好^^

对于任何感兴趣/面临类似问题的人来说,这里的代码对我来说可以正常工作:

数据表:

        <p:dataTable id="cTable" var="cTable" value="#{backingbean.lazyC}" paginator="true" 
            paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
            rowsPerPageTemplate="5,10,15" rows="10" sortMode="multiple" lazy="true" rendered="#{backingBean.cAvailable}">
            <p:columns value="#{backingBean.headerAllocationC}" var="colC" sortBy="#{cTable[colC.property]}">
                <f:facet name="header">
                    <h:outputText value="#{colC.header}"/>
                </f:facet>
                <h:outputText value="#{cTable[colC.property]}"/>                    
            </p:columns>
        </p:dataTable>

惰性数据模型:

public class LazyCDataModel extends LazyDataModel<cBean>{

    private static final long serialVersionUID = 1L;

    private List<cBean> datasource;

    public LazyCDataModel (List<cBean> datasource) {
    this.datasource = datasource;
    }
    @Override
    public List<cBean> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String,Object> filters){
        List<cBean> data = new ArrayList<cBean>();
        for (cBean c : datasource) {
            boolean match = true;
            if (filters != null) {
                for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
                    try {
                        String filterProperty = it.next();
                        Object filterValue = filters.get(filterProperty);
                        String fieldValue = String.valueOf(bestand.getClass().getField(filterProperty).get(bestand));
                        if (filterValue == null || fieldValue.startsWith(filterValue.toString())) {
                            match = true;
                        }
                        else {
                            match = false;
                            continue;
                        }
                    } catch (Exception e) {
                        match = false;
                    }
                }
            }
            if (match) {
                data.add(c);
            } 
        }
        if (multiSortMeta != null) {
            for (SortMeta sortMeta : multiSortMeta) {
                if (sortMeta.getSortField() != null) {
                    Collections.sort(data, new LazyCSort(sortMeta.getSortField(),sortMeta.getSortOrder()));
                }
            }
        }
        int dataSize = data.size();
        this.setRowCount(dataSize);
        if (dataSize > pageSize) {
            try {
                return data.subList(first, first+pageSize);
            } catch (IndexOutOfBoundsException e) {
                return data.subList(first, first+(dataSize%pageSize));
            }
        } else {
            return data;  
        }
    }
}

最后是我的 LazySorter:

public class LazyCSort implements Comparator<cBean>{
    private String sortField;
    private SortOrder sortOrder;
    public LazyBestandsSort(String sortField, SortOrder sortOrder) {
        this.sortField = sortField;
        this.sortOrder = sortOrder;
    }
    public int compare(cBean c1, cBean c2) {
        try {
            Field field1 = BestandsBean.class.getDeclaredField(this.sortField);
            Field field2 = BestandsBean.class.getDeclaredField(this.sortField);
            field1.setAccessible(true);
            field2.setAccessible(true);
            Object value1 = field1.get(bestand1);
            Object value2 = field2.get(bestand2);
            int value = ((Comparable) value1).compareTo(value2);
            return SortOrder.ASCENDING.equals(sortOrder) ? value : -1 * value;
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

注意: 在 LazySorter 中,我需要选择“cBean.class.getDeclaredField”,因为我在 cBean 中的字段是私有的。如果您有公共字段,则可以使用正常的“getField”,如 primefaces-Showcase 所示

【讨论】:

猜你喜欢
  • 2016-11-02
  • 2014-09-11
  • 2013-10-20
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
相关资源
最近更新 更多