clientRows和行之间分页时的冲突

时间:2014-03-06 12:31:38

标签: ajax jsf pagination richfaces

我开发了一个ExtendedDataModel,它支持服务器端的分页(通过查询数据库)。一切都按照我的预期运作,分页发生并且工作正常。但是,与此同时,我想用ajax加载客户端中每个页面的数据,所以我还想为我的extendedDataTable设置clientRows属性,而不仅仅是为每个逻辑页面划分的rows属性。一般来说,我希望能够设置clientRows<行,所以我在每个页面加载分页+ ajax。但是,目前只有当我设置clientRows =行时这才有效,这显然不是我需要的。

现在正在发生的事情是,如果我设置了clientRows属性,那么walk方法会收到一个范围,该范围只会到达clientRows行,并完全忽略row属性。如果我没有设置clientRows,则传递row属性(ok!)作为范围限制(totalRows)。我不知道这是否有帮助。

我在下面发布相关代码。

PaginationDataModel如下:

public abstract class PaginationDataModel<T> extends ExtendedDataModel<T> {

private SequenceRange cachedRange;
private Integer cachedRowCount;
private List<T> cachedList;
private Object rowKey;

/**
 * 
 * @param firstRow
 * @param numRows
 * @return
 */
public abstract List<T> getDataList(int firstRow, int numRows);
public abstract Object getKey(T t);
public abstract int getTotalCount();

@Override
public void walk(FacesContext ctx, DataVisitor dv, Range range, Object argument) {

    SequenceRange sr = (SequenceRange) range;

    if (cachedList == null || !equalRanges(cachedRange, sr)) {
        cachedList = getDataList(sr.getFirstRow(), sr.getRows());
        cachedRange = sr;
    }

    for (T t : cachedList) {
        if (getKey(t) == null) {
            /*
            * the 2nd param is used to build the client id of the table
            * row, i.e. mytable:234:inputname, so don't let it be null.
            */
            throw new IllegalStateException("found null key");
        }
        dv.process(ctx, getKey(t), argument);
    }

}

/*
* The rowKey is the id from getKey, presumably obtained from
* dv.process(...).
*/
@Override
public void setRowKey(Object rowKey) {
    this.rowKey = rowKey;
}

@Override
public Object getRowKey() {
    return rowKey;
}

@Override
public boolean isRowAvailable() {
    return (getRowData() != null);
}

@Override
public int getRowCount() {
    if (cachedRowCount == null) {
        cachedRowCount = getTotalCount();
    }
    return cachedRowCount;
}

@Override
public T getRowData() {
    for (T t : cachedList) {
        if (getKey(t).equals(this.getRowKey())) {
            return t;
        }
    }
    return null;
}

protected static boolean equalRanges(SequenceRange range1, SequenceRange range2) {
    if (range1 == null || range2 == null) {
        return range1 == null && range2 == null;
    } else {
        return range1.getFirstRow() == range2.getFirstRow() && range1.getRows() == range2.getRows();
    }
}

/*
* get/setRowIndex are used when doing multiple select in an
* extendedDataTable, apparently. Not tested. Actually, the get method is
* used when using iterationStatusVar="it" & #{it.index}.
*/
@Override
public int getRowIndex() {
    if (cachedList != null) {
        ListIterator<T> it = cachedList.listIterator();
        while (it.hasNext()) {
            T t = it.next();
            if (getKey(t).equals(this.getRowKey())) {
                return it.previousIndex() + cachedRange.getFirstRow();
            }
        }
    }
    return -1;
}

@Override
public void setRowIndex(int rowIndex) {
    int upperBound = cachedRange.getFirstRow() + cachedRange.getRows();
    if (rowIndex >= cachedRange.getFirstRow() && rowIndex < upperBound) {
        int index = rowIndex % cachedRange.getRows();
        T t = cachedList.get(index);
        setRowKey(getKey(t));
    }
}

@Override
public Object getWrappedData() {
    throw new UnsupportedOperationException("Not supported yet.");
}

@Override
public void setWrappedData(Object data) {
    throw new UnsupportedOperationException("Not supported yet.");

}

public List<T> getCachedList() {
    return cachedList;
}
}

带有dataScroller的extendedDataTable:

<rich:panel id="idPanel">
<rich:extendedDataTable value="#{someBean.someModel}" id="tableId"
   selectionMode="#{someBean.selectionMode}" selection="#{someBean.selection}" 
rows = "20" clientRows="#{someBean.clientRows}" var="someItem" style="height:300px;">

  <a4j:ajax execute="idPanel" event="selectionchange" listener="# {someBean.selectionListener}" render="@none" />
  columns and more columns...

  <f:facet name="footer"><rich:dataScroller for="tableId" page="#{someBean.currentPage}"  /></f:facet>

</rich:extendedDataTable>
</rich:panel>

谢谢你,原谅我的英语! :)

0 个答案:

没有答案