【问题标题】:How to do pagination in JSF 2如何在 JSF 2 中进行分页
【发布时间】:2014-10-06 17:22:12
【问题描述】:

我是 JSF 的新手,我正在尝试使用 <ui:repeat> 实现分页。我正在使用@ViewScoped,但目前我的状态没有保存。每次backing bean 重置页面信息时,都不会显示下一页。附上源码供参考。

WorkItemList.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    template="/WEB-INF/template/default.xhtml">

<ui:define name="content">
    <h:form id="form">

          <ui:repeat value="#{repeatPaginator.model}" var="listItem">
            <div>
                <h:outputText value="#{listItem}"/>
            </div>
        </ui:repeat>
        <h:commandButton value="&lt; prev" action="#{repeatPaginator.prev}"/>
        <h:outputText value="#{repeatPaginator.pageIndex} / #{repeatPaginator.pages}"/>
        <h:commandButton value="next &gt;" action="#{repeatPaginator.next}"/>
        <h:inputHidden value="#{repeatPaginator.pageIndex}"/>
    </h:form>
</ui:define>
</ui:composition>

支持 Bean - RepeatPaginator.java

package test;
@ManagedBean
@ViewScoped
public class RepeatPaginator implements Serializable{

    private static final long serialVersionUID = 1L;
    private static final int DEFAULT_RECORDS_NUMBER = 2;
    private static final int DEFAULT_PAGE_INDEX = 1;
    private TestDelegate delegate;
    private int records;
    private int recordsTotal;
    private int pageIndex;
    private int pages;
    private List<String> model;
    public RepeatPaginator() {
        delegate = new TestDelegate();
        this.records = DEFAULT_RECORDS_NUMBER;
        this.pageIndex = DEFAULT_PAGE_INDEX;
        // Get Model
        this.model = delegate.fetchCurrentList(getFirst(), getFirst()+records);
        this.recordsTotal = delegate.getListSize();

        if (records > 0) {
            pages = records <= 0 ? 1 : recordsTotal / records;

            if (recordsTotal % records > 0) {
                pages++;
            }

            if (pages == 0) {
                pages = 1;
            }
        } else {
            records = 1;
            pages = 1;
        }

        updateModel();
    }

    public void updateModel() {
        int fromIndex = getFirst();
        int toIndex = getFirst() + records;

        if(toIndex > this.recordsTotal) {
            toIndex = this.recordsTotal;
        }

         setModel(delegate.fetchCurrentList(fromIndex, toIndex));
    }

    public void next() {
        if(this.pageIndex < pages) {
            this.pageIndex++;
        }

        updateModel();
    }

    public void prev() {
        if(this.pageIndex > 1) {
            this.pageIndex--;
        }

        updateModel();
    }   

    public int getRecords() {
        return records;
    }

    public int getRecordsTotal() {
        return recordsTotal;
    }

    public int getPageIndex() {
        return pageIndex;
    }

    public int getPages() {
        return pages;
    }

    public int getFirst() {
        return (pageIndex * records) - records;
    }

    public List<String> getModel() {
        if(model==null)
            updateModel();
        return model;
    }

    public void setModel(List<String> model) {
        this.model = model;
    }

    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }
}

委托 - TestDelegate.java

@ViewScoped
public class TestDelegate {

    private List<String> list = new ArrayList<String>();
    public TestDelegate()
    {
        this.list.add("Item 1");
        this.list.add("Item 2");
        this.list.add("Item 3");
        this.list.add("Item 4");
        this.list.add("Item 5");
        this.list.add("Item 6");
        this.list.add("Item 7");
        this.list.add("Item 8");
        this.list.add("Item 9");
        this.list.add("Item 10");
        this.list.add("Item 11");
    }

    public List<String> fetchCurrentList(int from, int to)
    {
        return list.subList(from, to);
    }

    public int getListSize()
    {
        return this.list.size();
    }
}

【问题讨论】:

    标签: jsf pagination jsf-2.2


    【解决方案1】:

    @ViewScoped bean 并非“一直神奇地存在”。在请求结束时,它的值将被序列化并且 bean 被破坏。

    这会在下一个请求开始时重新构造 bean(单击下一步)。您的 Container 将再次反序列化存储的值,以返回 bean 的实际状态。 但是:这发生在 Bean-Construction 之后,这意味着当您尝试使用bean 的Constructor 中的值时,什么都不会恢复。

    将您的逻辑移动到您使用@PostConstruct 注释的方法中 - 然后将加载所有值并且您可以获取正确的结果。一旦恢复了 bean 的先前状态,容器就会调用带有 @PostConstruct 注释的方法。

    当您开始使用 ManagedProperties 或 CDI-Injections 时,这一点变得很重要。

    public RepeatPaginator() {
       //no serialized data available here, Good location to initialize some stuff 
       //that is independent.
       delegate = new TestDelegate();
       this.records = DEFAULT_RECORDS_NUMBER;
       this.pageIndex = DEFAULT_PAGE_INDEX;
    }
    
    @PostConstruct
    public void init() {
            //Here the ViewScoped values are restored. We can start to use them.
    
            // Get Model
            this.model = delegate.fetchCurrentList(getFirst(), getFirst()+records);
            this.recordsTotal = delegate.getListSize();
    
            if (records > 0) {
                pages = records <= 0 ? 1 : recordsTotal / records;
    
                if (recordsTotal % records > 0) {
                    pages++;
                }
    
                if (pages == 0) {
                    pages = 1;
                }
            } else {
                records = 1;
                pages = 1;
            }
    
            updateModel();
        }
    

    【讨论】:

    • 感谢 dognose 的回答,我已将代码移至“@PostConstruct”方法。但我仍然有问题。我尝试调试代码,我可以看到在单击“下一步”时,“@PostConstruct”中的模型仍然为 NULL,而不是具有来自先前状态的值。你能解释一下为什么会这样吗?
    • 我想通了..我错误地使用了“@named”和“@managedbean”..现在它工作正常..感谢您的快速响应。
    • @Adwin 不客气。 ps.:如果您对它感到满意,您可以接受答案作为正确的解决方案。 (激励正在帮助的人:P)
    猜你喜欢
    • 2011-07-19
    • 2011-12-20
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    • 2019-04-23
    • 2019-08-17
    • 2017-10-03
    相关资源
    最近更新 更多