Spring + Thymeleaf - 如何实现列表的分页

Duš*_*ský 13 spring pagination thymeleaf

我正在使用Spring + Thymeleaf开发一个简单的应用程序.在其中一个页面上,我有一个需要分页的项目列表.

理想情况下,我只想将currPageNo(当前页面的数量)和numOfPages(总页数)变量发送到视图,其余的工作将在那里完成(这是一个演示问题而且无关与业务逻辑).但是,如果最干净的解决方案要求我先在控制器中进行一些计算,我会接受它作为一个小恶魔.

我想以下面的形式获取页面列表.

<Prev | 1 | ... | 3 | 4 | 5 | 6 | 7 | ... | 15 | Next>
Run Code Online (Sandbox Code Playgroud)

我只能得到以下解决方案.它有效,但我相信你会同意它非常混乱,真的很难阅读.

此外,除了currPageNonumOfPages我不得不再向视图发送两个变量.理想的解决方案不需要我这样做.

firstPageNo = Math.max(2, currPageNo - 2)
lastPageNo = Math.min(numOfPages - 1, currPageNo + 2)
Run Code Online (Sandbox Code Playgroud)

我的代码的当前版本如下.

<ul>
    <li th:if="${currPageNo &gt; 1}">
        <a th:href="@{/items.html(pageNo = ${currPageNo - 1})}" href="">&lt; Prev</a>
    </li>
    <li th:class="${currPageNo == 1} ? 'selected'">
        <a th:href="@{/items.html(pageNo = 1)}" th:if="${currPageNo &gt; 1}" href="">1</a>
        <span th:if="${currPageNo == 1}">1</span>
    </li>
    <li th:if="${currPageNo &gt;= 5}">
        ...
    </li>
    <li th:each="pageNo : ${#numbers.sequence(firstPageNo, lastPageNo)}"  th:class="${currPageNo == pageNo} ? 'selected'">
        <a th:href="@{/items.html(pageNo = ${pageNo})}" th:if="${pageNo != currPageNo}" th:text="${pageNo}" href="">2</a>
        <span th:if="${pageNo == currPageNo}" th:text="${pageNo}">2</span>
    </li>
    <li th:if="${currPageNo &lt;= (numOfPages - 4)}">
        ...
    </li>
    <li th:class="${currPageNo == numOfPages} ? 'selected'">
        <a th:href="@{/items.html(pageNo = ${numOfPages})}" th:if="${currPageNo &lt; numOfPages}" th:text="${numOfPages}" href="">10</a>
        <span th:if="${currPageNo == numOfPages}" th:text="${numOfPages}">1</span>
    </li>
    <li th:if="${currPageNo &lt; numOfPages}">
        <a th:href="@{/items.html(pageNo = ${currPageNo + 1})}" href=""> Next &gt;</a>
    </li>
</ul>
Run Code Online (Sandbox Code Playgroud)

以下列表总结了我想摆脱的问题.据我所知,其中一些是平台所固有的,但是,这个列表似乎很长,而且代码很乱.

  • 无需发送的预计算值firstPageNo,并lastPageNo从控制器的看法.
  • 必须使用&lt;而不是<在表达式中.
  • 必须使用具有互斥条件的锚点和跨度,以便浏览器不使用当前页面的链接.

我也欢迎任何其他有关如何提高代码质量的建议.


我知道也许这个问题可能更适合Code Review网站,但是,由于Thymeleaf似乎是一个拥有微小用户群的技术,我希望在Stack Overflow上有一个合理的答案,它有更多的用户基地(我相信).

但是,如果在这里真的不欢迎这样的问题,请考虑将其移至正确的网站而不是关闭它,以便我得到我需要的建议.

小智 19

http://www.javacodegeeks.com/2013/03/implement-bootstrap-pagination-with-spring-data-and-thymeleaf.html中描述的解决方案类似

但没有在Spring Pageable周围使用包装器

<div class="table-pagination">
    <ul class="pagination">
        <li th:class="${contactsPage.number eq 0} ? 'disabled' : ''">
            <a th:if="${not contactsPage.firstPage}" th:href="@{${'/contacts'}(page=${contactsPage.number-1},size=${contactsPage.size})}">Previous</a>
            <a th:if="${contactsPage.firstPage}" href="javascript:void(0);">Previous</a>
        </li>

        <li th:each="pageNo : ${#numbers.sequence(0, contactsPage.totalPages - 1)}" th:class="${contactsPage.number eq pageNo}? 'active' : ''">
            <a th:if="${contactsPage.number  eq pageNo}" href="javascript:void(0);">
                <span th:text="${pageNo + 1}"></span>
            </a>
            <a th:if="${not (contactsPage.number  eq pageNo)}" th:href="@{${'/contacts'}(page=${pageNo},size=${contactsPage.size})}">
                <span th:text="${pageNo + 1}"></span>
            </a>

        </li>
        <li th:class="${contactsPage.number + 1 ge contactsPage.totalPages} ? 'disabled' : ''">
            <a th:if="${not contactsPage.lastPage}" th:href="@{${'/contacts'}(page=${contactsPage.number+1},size=${contactsPage.size})}">Next</a>
            <a th:if="${contactsPage.lastPage}" href="javascript:void(0);">Next</a>
        </li>
    </ul>
</div>
Run Code Online (Sandbox Code Playgroud)

  • 请包含一些文字,例如带代码的说明. (3认同)
  • 不要只是转储代码......也要添加一些肉. (3认同)

小智 2

另一种选择是本瑟利的解决方案。我们已经实现了它并且运行顺利:http://bthurley.wordpress.com/2012/07/18/spring-mvc-with-restful-datatables/

它缺少几个项目,例如搜索的过滤器参数,但您可以通过 PagingCriteria 对象轻松添加,并确保将其添加到 TableParamArgumentResolver 上。

public class TableParamArgumentResolver implements WebArgumentResolver {

    private static final String S_ECHO           = "sEcho";
    private static final String I_DISPLAY_START  = "iDisplayStart";
    private static final String I_DISPLAY_LENGTH = "iDisplayLength";
    private static final String I_SORTING_COLS   = "iSortingCols";

    private static final String I_SORT_COLS      = "iSortCol_";
    private static final String S_SORT_DIR       = "sSortDir_";
    private static final String S_DATA_PROP      = "mDataProp_";
    private static final String I_DATA_SEARCH    = "sSearch";

    public Object resolveArgument(MethodParameter param, NativeWebRequest request)
            throws Exception {
        TableParam tableParamAnnotation = param.getParameterAnnotation(TableParam.class);

        if (tableParamAnnotation != null) {
            HttpServletRequest httpRequest = (HttpServletRequest) request.getNativeRequest();

            String sEcho = httpRequest.getParameter(S_ECHO);
            String sDisplayStart = httpRequest.getParameter(I_DISPLAY_START);
            String sDisplayLength = httpRequest.getParameter(I_DISPLAY_LENGTH);
            String sSortingCols = httpRequest.getParameter(I_SORTING_COLS);
            String sSearch = httpRequest.getParameter(I_DATA_SEARCH);

            Integer iEcho = Integer.parseInt(sEcho);
            Integer iDisplayStart = Integer.parseInt(sDisplayStart);
            Integer iDisplayLength = Integer.parseInt(sDisplayLength);
            Integer iSortingCols = Integer.parseInt(sSortingCols);

            List<SortField> sortFields = new ArrayList<SortField>();
            for (int colCount = 0; colCount < iSortingCols; colCount++) {
                String sSortCol = httpRequest.getParameter(I_SORT_COLS + colCount);
                String sSortDir = httpRequest.getParameter(S_SORT_DIR + colCount);
                String sColName = httpRequest.getParameter(S_DATA_PROP + sSortCol);
                sortFields.add(new SortField(sColName, sSortDir));
            }

            PagingCriteria pc = new PagingCriteria(iDisplayStart, iDisplayLength, iEcho, sortFields, sSearch);

            return pc;
        }

        return WebArgumentResolver.UNRESOLVED;
    }
}
Run Code Online (Sandbox Code Playgroud)