16

Spring + Thymeleaf を使用して簡単なアプリケーションを開発しています。ページの 1 つに、ページ分割する必要があるアイテムのリストがあります。

理想的には、currPageNo(現在のページの数) とnumOfPages(ページの総数) 変数のみをビューに送信し、残りの作業はそこで行われます (これはプレゼンテーションの問題であり、何もする必要はありません)。ビジネスロジックと一緒に)。ただし、最もクリーンなソリューションで最初にコントローラーで何らかの計算を行う必要がある場合、私はそれを小さな悪として受け入れます。

次の形式でページのリストを取得したいと思います。

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

私は次の解決策しか思いつきませんでした。うまくいきますが、非常に面倒で読みにくいことに同意していただけると思います。

さらに、 と に加えて、さらにcurrPageNo2numOfPagesつの変数をビューに送信する必要がありました。理想的な解決策は、私がそれを行う必要がないことです。

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

私のコードの現在のバージョンは次のとおりです。

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

次のリストは、私が最も取り除きたい問題をまとめたものです。それらのいくつかはプラットフォームに固有のものであることは理解していますが、それでもリストが長く、コードが乱雑であるようです。

  • firstPageNo事前に計算された値をlastPageNoコントローラーからビューに送信する必要があります。
  • &lt;式の代わりに使用する必要<があります。
  • ブラウザが現在のページへのリンクを使用しないようにするために、相互に排他的な条件でアンカーとスパンの両方を使用する必要があります。

また、コードの品質を向上させる方法についてのその他の提案も歓迎します。


おそらくこの質問は Code Review サイトの方が適していることは理解していますが、Thymeleaf はまだユーザー ベースが小さいテクノロジーのように思われるため、ユーザー数がはるかに多い Stack Overflow で合理的な回答が得られることを期待しています。ベース(私は信じています)。

ただし、そのような質問が本当に歓迎されない場合は、必要なアドバイスが得られるように、サイトを閉じるのではなく、適切なサイトに移動することを検討してください.

4

6 に答える 6

2

別のオプションは、Ben Thurley のソリューションです。私たちはそれを実装し、スムーズに動作しています: 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;
    }
}
于 2013-09-20T10:55:52.367 に答える