JSF、RichFaces、分页

2023-11-24

我知道这里有很多关于 JSF 分页的帖子,但没有一个让我满意。

为了将相当大的数据分割成页面,我将使用 RichFaces 数据滚动器组件。

它似乎适合于此,但看起来它是“人工”分页的。

我不喜欢这里的是它加载所有数据,然后只显示其中的一部分。至少看起来是这样。如我错了请纠正我。

Rich Faces 有很好的演示,但由于某种原因,他们跳过了 bean 定义——仅使用 xhtml。 我看到一些关于 ExtendedDataModel 的提及,但我发现的唯一示例并没有给我留下深刻的印象。 为什么我应该有 5 个屏幕代码来显示数据子集?

老实说,像分页这样简单的问题在 JSF 中却非常复杂,我真的不明白为什么。

所以我的问题是: 1. Richfaces中是否可以只加载一页数据 2.不将其存储到会话中(我的意思是实际数据未列出状态-当前页面等)

我只对 richfaces lib 感兴趣,因为它已经在我的项目中使用了,而不是引入对其他东西的依赖

提前感谢


在 RichFaces 论坛上讨论后,提出了以下解决方案(感谢 Brendan Healey):

RichLazyDataModel.java

/**
 * Extended data model
 * @author Brendan Healey
 */
public abstract class RichLazyDataModel<T> extends ExtendedDataModel<T> {

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

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;
}

}

列表状态.java

/**
 * Holds list state
 */
public class ListState implements Serializable {

private int page;

private Map<String, Serializable> searchCriteria = new HashMap<String, Serializable>();

public int getPage() {
    return page;
}

public void setPage(int page) {
    this.page = page;
}

public Map<String,Serializable> getSearchCriteria() {
    return searchCriteria;
}

}

CardsBean.java

@ManagedBean(name="cardsBean")
public class CardsBean {

@ManagedProperty("#{cardService}")
private CardService cardService;

private ListState state;

private RichLazyDataModel<Card> cardsModel = new RichLazyDataModel<Card>() {
    @Override
    public List<Card> getDataList(int firstRow, int numRows) {
        MyUserDetails user = SecurityUtils.getCurrentUser();
        return cardService.findUserCards(user.getUser(), firstRow, numRows, state.getSearchCriteria());
    }

    @Override
    public Object getKey(Card card) {
        return card.getId();
    }

    @Override
    public int getTotalCount() {
        MyUserDetails user = SecurityUtils.getCurrentUser();
        return cardService.countUserCards(user.getUser(), state.getSearchCriteria());
    }
};


public RichLazyDataModel<Card> getCards() {
    return cardsModel;
}

public String getSearchString() {
    return (String)state.getSearchCriteria().get("searchString");
}

public int getCurrentPage() {
    return state.getPage();
}

public void setCurrentPage(int page) {
    state.setPage(page);
}

public void setSearchString(String searchString) {
    state.getSearchCriteria().put("searchString", searchString);
}

public void setCardService(CardService cardService) {
    this.cardService = cardService;
}

public boolean isPinned() {
    return Boolean.TRUE.equals(state.getSearchCriteria().get("pinned"));
}

public void setPinned(boolean pinned) {
    state.getSearchCriteria().put("pinned", pinned);
}

public void togglePinned() {
    setPinned(!isPinned());
}

@PostConstruct
public void init() {
    state = getFromSession("cardsList", null);
    if (state == null) {
        state = new ListState();
        storeInSession("cardsList", state);
    }
}

public <T extends Serializable> T getFromSession(String name, T defaultValue) {
    T ret = (T) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(name);
    if (ret == null) {
        ret = defaultValue;
    }
    return ret;
}

public void storeInSession(String name, Serializable obj) {
    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(name, obj);
}
}

cards.xhtml(部分)

...

<h:form>

  <rich:dataGrid value="#{cardsBean.cards}" var="card" columns="2" elements="20" first="#{cardsBean.currentPage}" style="margin:0 auto;width:70em" id="cardsTable">
      <f:facet name="header">
          <h:inputText value="#{cardsBean.searchString}">
              <a4j:ajax event="keyup" render="cardsTable@body, cardsTable@footer">
                <a4j:attachQueue requestDelay="700" ignoreDupResponses="true" />
              </a4j:ajax>

          </h:inputText>
      </f:facet>

      <rich:panel id="cd">
          <ui:include src="WEB-INF/parts/card.xhtml">
              <ui:param name="card" value="#{card}"/>
          </ui:include>


      </rich:panel>

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

  </rich:dataGrid>

  </h:form>
...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSF、RichFaces、分页 的相关文章

随机推荐

  • 在运行时创建继承抽象类并实现接口的类型

    我们的架构广泛使用存储库模式 我们为大多数存储库提供了一个抽象基类 它实现了一些常见的功能 例如获取 加载 列表等 这个基类有一个对应的接口IRepository 它定义了抽象类的公共方法 大多数实体都有对应的存储库接口 例如Foo 实体有
  • .htaccess 将根目录重定向到index.php

    我需要重定向自http example com to http example com index php 用这个 DirectoryIndex index php
  • 使用 GCC 查找无法访问的函数(“死代码”)

    我正在寻找一种在 非常 大型 C 项目中查找静态无法访问的函数的方法 我曾尝试使用 doxygen 和此处建议的其他静态分析工具 但似乎该项目太复杂 他们无法处理 最后我决定使用 GCC 工具 g gprof gcov 等 是最安全的选择
  • Flutter 中的元素是什么?

    我很难理解 Flutter 中的元素是什么 来自文档 树中特定位置的小部件的实例化 我想现在我必须问 那棵树是什么 起初 我以为树指的是小部件的状态 但 StatelessWidget 也有 createElement 所以情况似乎并非如此
  • 使用较小的默认对齐方式重载 new 运算符

    C 17 引入过度对齐数据的动态内存分配 除了现有的std max align t 基本对齐 它补充说 STDCPP DEFAULT NEW ALIGNMENT 运算符 new 保证的最小对齐 通过 MSVC2017 64 位编译 这些常量
  • 如何使用 Apache POI 读取具有日期的 Excel 单元格?

    我正在使用 Apache POI 3 6 我想读取一个具有如下日期的 Excel 文件8 23 1991 switch cell getCellType case HSSFCell CELL TYPE NUMERIC value NUMER
  • 将 Quartz.Net 与 UI 相结合

    我一直在从事 MVC3 项目 我刚刚在我的应用程序中使用 Quartz Net 创建了示例电子邮件发送作业 这次 我需要在我的MVC3项目中构建一个作业调度系统 该场景完全基于 UI 这意味着 系统用户必须通过 UI 输入调度频率 例如定义
  • Petri网绘图和代码生成

    是否有任何软件可以绘制 Petri 网并从那里生成任何源代码 源代码可以采用任何已知的编程语言 稍微不太理想的选择是以某种开放格式 例如 XML 或任何其他数据语言 在基于文本的文件中输出仅包含 Petri 网图描述的文件 然后我可以自己编
  • 向累积图添加 95% 置信限

    我想使用 R 添加一条抛物线 表示 95 的置信极限到这个抛硬币图 x lt sample c 1 1 60000 replace TRUE plot ts cumsum x ylim c 250 250 Here is an exampl
  • AttributeError:模块“os”没有属性“uname”

    当我做 gt gt gt import os gt gt gt os uname 我收到一个属性错误 如下所示 Traceback most recent call last File
  • 如何处理python请求中的401(未经授权)

    我想要做的是从站点获取 如果该请求返回 401 则重做我的身份验证摆动 可能已过时 并重试 但我不想尝试第三次 因为那将是我的身份验证摇摆不定的凭证 有没有人有一个很好的方法来做到这一点 并且不涉及丑陋的代码 最好是在 python req
  • Python:Xlib——如何升起(置顶)窗口?

    我尝试过使用 win configure stack mode X TopIf win set input focus X RevertToParent X CurrentTime 然而 即使我的窗口管理器上没有任何焦点丢失预防措施 这也不
  • 是否可以在ios 9中获取wifi信号强度

    我想检查 WIFI 信号强度 以便在 WIFI 信号弱时显示某种消息 我发现在 iOS 8 及更早版本中这是不可能的 iOS 9 中可以获取 wifi 信号强度吗 如果答案是肯定的那么如何 是的 在 iOS 9 中是可能的 查看一下NE热点
  • Oreo 版本问题不支持此图像的编辑

    Oreo 版本问题中的此图像不支持编辑 此图像不支持编辑 当从 Oreo 版本移动设备中的图库中选择图像时 会显示此 Toast 我已经问过这个问题了 但没有人回复我 请检查我的代码并尽快恢复 这是我的代码 Override public
  • 使用 pyinotify 监视文件创建,但等待它完全写入磁盘

    我正在使用 pyinotify 来监视文件夹中何时创建文件 当创建某些文件时 我想移动它们 问题是 一旦创建文件 显然 我的程序就会尝试移动它 甚至在它完全写入磁盘之前 有没有办法让 pyinotify 等到文件完全写入磁盘后再通知我它已创
  • CSS 在 Chrome 中不起作用

    我正在处理的网站的此页面未加载 CSS http www thesanfordcenter net sanford center 它只发生在 Chrome 中 但不是缓存问题 因为同样的问题也发生在另一台计算机上的 Chrome 中 并且我
  • 将隐式 ExecutionContext 传递给包含的对象/调用的方法

    我正在使用 Scala 2 10 futures 创建一个异步库 库的构造函数采用一系列实现特定特征的用户定义对象 然后库类上的方法将一些数据逐一发送到用户定义的对象中 我希望用户提供ExecutionContext用于设置主实例时的异步操
  • LINQ/Lambda 相当于 SQL

    我有一个 IEnumerable 其中包含带有 id 的对象列表 我想选择那些 ID 为 1 2 7 8 9 10 和 11 的对象 我不知道等效 SQL 语句的 LINQ Lambda 等效项 select where id in 1 2
  • 从 WebView 启动自定义 Android 应用程序

    我有一个 HTML 文件 如果我在 Android 本机浏览器中打开它 它就会启动一个应用程序 但是当我尝试在 WebView 中打开相同的应用程序时 它无法启动该应用程序 并且显示 网页不可用 我认为我的 WebView 无法处理为应用程
  • JSF、RichFaces、分页

    我知道这里有很多关于 JSF 分页的帖子 但没有一个让我满意 为了将相当大的数据分割成页面 我将使用 RichFaces 数据滚动器组件 它似乎适合于此 但看起来它是 人工 分页的 我不喜欢这里的是它加载所有数据 然后只显示其中的一部分 至