2013-08-28 10 views
10

Pracuję nad prostą aplikacją przy użyciu Spring + Thymeleaf. Na jednej ze stron mam listę przedmiotów, które muszą być pogrupowane.Spring + Thymeleaf - jak zaimplementować paginację dla listy

Idealnie chciałbym przesłać tylko currPageNo (numer bieżącej strony) i numOfPages (całkowita liczba stron) zmiennych do widoku, a reszta pracy zostanie wykonana tam (jest to prezentacja problem i nie ma nic wspólnego z logiką biznesową). Gdyby jednak najczystsze rozwiązanie wymagało ode mnie najpierw dokonania obliczeń w sterowniku, uznałbym to za małe zło.

Chciałbym uzyskać listę stron w poniższym formularzu.

<Prev | 1 | ... | 3 | 4 | 5 | 6 | 7 | ... | 15 | Next> 

Mogłem przyjść tylko z następującym rozwiązaniem. Działa, ale wierzę, że zgodzisz się, że jest bardzo brudny i naprawdę trudny do odczytania.

Ponadto, oprócz currPageNo i numOfPages musiałem wysłać dwie dodatkowe zmienne do widoku. Idealne rozwiązanie nie wymagałoby tego.

firstPageNo = Math.max(2, currPageNo - 2) 
lastPageNo = Math.min(numOfPages - 1, currPageNo + 2) 

Obecna wersja mojego kodu następuje.

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

Poniższa lista podsumowuje problemy, które chciałbym pozbyć się najbardziej. Rozumiem, że niektóre z nich są nieodłącznie związane z platformą, ale mimo to lista wydaje się być zamknięta, a kod jest niechlujny.

  • uwzględniając wysłać precomputed wartości firstPageNo i lastPageNo do widoku z kontrolera.
  • Konieczność użycia &lt; zamiast < w wyrażeniach.
  • Posiadanie zarówno kotwicy, jak i przęsła z wzajemnie wykluczającymi się warunkami, aby przeglądarka nie korzystała z linku do bieżącej strony.

Z zadowoleniem przyjmuję również wszelkie inne sugestie dotyczące poprawy jakości kodu.


Rozumiem, że może to pytanie byłoby lepsze dopasowanie do serwisu Code Review, ale, jak Thymeleaf wydaje się technologię z małym bazy użytkowników jeszcze, spodziewam rozsądną odpowiedź raczej tutaj na przepełnienie stosu , który ma znacznie większą bazę użytkowników (jak sądzę).

Jeśli jednak takie pytanie nie jest tutaj mile widziane, należy rozważyć przeniesienie go na właściwą stronę zamiast jej zamknięcia, aby uzyskać potrzebne porady.

Odpowiedz

2

Inną opcją będzie rozwiązanie Ben Thurleya. Wdrożyliśmy go i działa on sprawnie: http://bthurley.wordpress.com/2012/07/18/spring-mvc-with-restful-datatables/

Brakuje par przedmiotów, takich jak argument filtru dla wyszukiwania, ale można go łatwo dodać za pomocą obiektu PagingCriteria i dodać go do 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; 
    } 
} 
18

podobne do rozwiązania opisanego w http://www.javacodegeeks.com/2013/03/implement-bootstrap-pagination-with-spring-data-and-thymeleaf.html

ale bez użycia owijkę wokół Wiosna stronicowalnej

<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> 
+2

Proszę podać tekst, na przykład wyjaśnienie z kodem. –

+2

Nie po prostu zrzuć kod ... dodaj trochę mięsa do niego. – Werner

+1

Uwaga: od tej pory musisz zastąpić 'firstPage' i' lastPage' opcjami 'first' i' last'. – membersound

1

mam to już prawie gotowy, mam nadzieję, że pomaga ....

<div class="tag-box tag-box-v7 text-justify"> 
    <div class="text-center"> 
     <ul class="pagination" th:with="elementsperpage=2, blocksize=10, pages=${page2th.Number}/${elementsperpage}, wholepages=${format.format(pages)}, 
whole=(${page2th.Number}/${blocksize})+1, wholex=${format.format(whole)}, startnlockpage=${wholepages}*${blocksize+1}, endblockpage=${wholepages}*${blocksize+1}, 
startpage=${wholex-1}*${blocksize}, endpage=(${wholex}*${blocksize})+1"> 

      <li> 
       <a th:if="${startpage gt 0}" th:href="@{${'/viewannouncements?p='}+${startpage}}">&lt;&lt;</a> 
       <a th:if="${startpage eq 0}" href="javascript:void(0);">&lt;&lt;</a> 
      </li> 

      <li th:each="pageNo : ${#numbers.sequence(endpage-11, (endpage lt page2th.TotalPages)? endpage-2 : page2th.TotalPages-1)}" 
      th:class="${page2th.Number eq pageNo}? 'active' : ''"> 
        <a th:if="${page2th.Number eq pageNo}" href="javascript:void(0);"> 
         <span th:text="${pageNo + 1}"></span> 
        </a> 
        <a th:if="${not (page2th.Number eq pageNo)}" th:href="@{${'/viewannouncements?p='}+${pageNo+1}}"> 
         <span th:text="${pageNo + 1}"></span> 
        </a> 
      </li> 

      <li> 
       <a th:if="${(endpage*elementsperpage) le (page2th.TotalElements)}" th:href="@{${'/viewannouncements?p='}+${endpage}}">&gt;&gt;</a> 
       <a th:if="${(endpage*elementsperpage) le (page2th.TotalElements)}" href="javascript:void(0);"></a> 
      </li> 



     </ul> 
    </div> 
</div> 
Powiązane problemy