Пейджинг / пейджер JSF2 для повторителя

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

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

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

Ваше здоровье...


person Sven    schedule 19.08.2010    source источник
comment
Вы используете Richfaces в своем приложении?   -  person Maxim Manco    schedule 19.08.2010
comment
Я не. Но я мог бы, если бы это мне помогло :-)   -  person Sven    schedule 19.08.2010


Ответы (2)


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

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

}

Фасоль:

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>
person Maxim Manco    schedule 19.08.2010
comment
@mmanco внутри UIRepeater, можете ли вы динамически создавать ссылки на команды? - person John John Pichler; 28.11.2012

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

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

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

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

И последнее, но не менее важное: существует множество библиотек компонентов, которые выполняют всю работу в одном компоненте. Например, RichFaces _ 22_ и PrimeFaces _ 23_ (также можно сделать ajaxical).

person BalusC    schedule 19.08.2010
comment
Хм, я действительно удивлен, что вы не включили типичный пример "BalusC-kickoff". :) Тем не менее, мне все равно нравится подход БД. - person alexander; 15.08.2015
comment
@BalusC: Привет, BalusC, кажется, что в Primefaces вводится ui: повторная разбивка на страницы после проверки этой ссылки http://blog.primefaces.org/?p=1808, но ссылка в этой статье недействительна. Не могли бы вы прояснить нам этот момент? Есть ли решение Primefaces для ui: повторная разбивка на страницы? - person Jad Chahine; 25.09.2016
comment
@Jad: это <p:dataList>. - person BalusC; 25.09.2016
comment
Большое спасибо! Я добираюсь до этого http://www.primefaces.org/showcase/ui/data/dataList.xhtml - person Jad Chahine; 25.09.2016