JSF2 Paging / Pager for Repeater - PullRequest
       10

JSF2 Paging / Pager for Repeater

14 голосов
/ 19 августа 2010

Знаете ли вы это чувство, когда каждый код, который вы пишете, работает мгновенно и вы нарушаете свой график :-P Это похоже на «о да, теперь у меня есть время, чтобы сделать его идеальным». Вот где я сейчас нахожусь ^^

Итак, я реализовал ретранслятор с JSF (ui: repeat), и я подумал о пейджинге для всех сущностей. Есть ли простой способ сделать это? Какие моменты я должен думать?

Было бы неплохо, если бы кто-нибудь помог мне. Мои навыки googleskills мне пока не помогли: -P

Приветствия ...

Ответы [ 2 ]

21 голосов
/ 19 августа 2010

Вот простой пример, который должен дать вам представление о том, как это реализовать.

RepeatPaginator:

public class RepeatPaginator {

    private static final int DEFAULT_RECORDS_NUMBER = 2;
    private static final int DEFAULT_PAGE_INDEX = 1;

    private int records;
    private int recordsTotal;
    private int pageIndex;
    private int pages;
    private List<?> origModel;
    private List<?> model;

    public RepeatPaginator(List<?> model) {
        this.origModel = model;
        this.records = DEFAULT_RECORDS_NUMBER;
        this.pageIndex = DEFAULT_PAGE_INDEX;        
        this.recordsTotal = model.size();

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

        this.model = origModel.subList(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<?> getModel() {
        return model;
    }

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

}

Bean:

public class TestBean {

    private List<String> list;
    private RepeatPaginator paginator;

    @PostConstruct
    public void init() {
        this.list = new ArrayList<String>();
        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");
        paginator = new RepeatPaginator(this.list);
    }

    public RepeatPaginator getPaginator() {
        return paginator;
    }

}

XHTML:

<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"
    template="/WEB-INF/template/default.xhtml">

<ui:define name="content">
    <h:form>
        <ui:repeat value="#{testBean.paginator.model}" var="listItem">
            <div>
                <h:outputText value="#{listItem}"/>
            </div>
        </ui:repeat>
        <h:commandButton value="&lt; prev" action="#{testBean.paginator.prev}"/>
        <h:outputText value="#{testBean.paginator.pageIndex} / #{testBean.paginator.pages}"/>
        <h:commandButton value="next &gt;" action="#{testBean.paginator.next}"/>
        <h:inputHidden value="#{testBean.paginator.pageIndex}"/>
    </h:form>
</ui:define>
</ui:composition>
9 голосов
/ 19 августа 2010

Нумерация страниц на самом деле легко.Вы просто должны передавать один или два параметра: firstrow и, необязательно, rowcount (которые также могут храниться на стороне сервера).Когда конечный пользователь нажимает Далее , вы просто увеличиваете значение firstrow на значение rowcount.Когда конечный пользователь нажимает Back , вы просто уменьшаете значение firstrow до значения rowcount.Вам нужно только проверить, не превышает ли он границы 0 и totalrows, и соответственно изменить.

Затем, основываясь на желаемых значениях firstrow и rowcount, вы точно знаете, какие данныедля отображения.Если все данные уже находятся в некотором List в памяти Java, тогда вы просто используете List#subList(), чтобы получить из него подсписок для отображения.Однако неэффективно дублировать всю таблицу базы данных в память Java.Это может не навредить, когда всего 100 строк, но когда это намного больше, и / или вы дублируете его для каждого отдельного пользователя, тогда приложению очень скоро не хватит памяти.

В этом случае вы бы предпочли разбивать на страницы на уровне БД.Например, в MySQL вы можете использовать предложение LIMIT для получения подмножества результатов из БД.JPA / Hibernate даже предоставляет способы использования setFirstResult() и setMaxResults() методов Query и Criteria соответственно.Вы можете найти примеры в this и this answer.

Вы можете найти базовый JSF 1.2 целевой пример запуска Google-подобной нумерации страниц (и сортировки) в эта статья .Он использует компоненты Tomahawk, но в JSF 2.0 вы можете просто оставить их, сделав компонент @ViewScoped (заменяет t:saveState) и используя ui:repeat (заменяет t:dataList).

И последнее, но не менее важноеЕсть много библиотек компонентов, которые делают все работы в одном компоненте.Например, RichFaces <rich:datascroller> и PrimeFaces <p:dataTable paginator="true"> (также может быть сделано ajaxical ).

...