使用 Thymeleaf 分页时如何优雅地保留过滤器参数?
How can I elegantly preserve filter parameters when paginating with Thymeleaf?
在我的许多页面上,我有几个选项可以对一长串结果进行排序或过滤。
我希望在有人翻阅数据时正确保留这些选择。例如:
- 开始查看所有工单的列表。 (
/tickets
)
- 搜索所有类似 "foo." (
/tickets?query=foo
) 的门票
- 转到下一页。 (
/tickets?query=foo&page=2
)
- 请参阅 "foo" 等门票的下一页,而不是 "all tickets." 的第二页(例如,不是
/tickets?page=2
)
在JSP中,我想到了这样的解决方案:
<c:if test="${page.hasNext()}">
<spring:url value="" var="nextLink">
<c:forEach items="${param}" var="curParam">
<c:if test="${curParam.key != 'page'}">
<spring:param name="${curParam.key}" value="${curParam.value}"/>
</c:if>
</c:forEach>
<spring:param name="page" value="${page.nextPageable().pageNumber}"/>
</spring:url>
<li>
<a href="${nextLink}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
这基本上构造了一个新的 URL 指向与当前页面相同的路径,但是 adds/replaces 它的查询参数的 "path" 参数。
它在 JSP 中非常丑陋,但我在 Thymeleaf 中完全看不到真正做到这一点的方法?
或者,也许有一些更好的方法可以使用一些我还没有遇到过的 Spring 或 Thymeleaf 功能来做到这一点?
我希望有一个简洁的 Thymeleaf 片段,我可以在需要分页的任何地方重复使用。到目前为止,这就是我所拥有的,但它最终缺少 "query" 参数等。(我不想在这里对查询参数进行硬编码,因为这会限制此分页代码的可重用性)
<li th:if="${page.hasNext()}">
<a href="pagination.html" th:href="@{''(page=${page.nextPageable().pageNumber})}" aria-label="next">
<span aria-hidden="true">»</span>
</a>
</li>
Dandelion Datatables 是一个可以帮助您避免重新发明轮子的项目。
http://dandelion.github.io/components/datatables/
也许这对将 HTML 和 Spring 与 Thymeleaf 一起使用的人有用。
在我的例子中,我将 thymeleaf 与 spring 一起使用。我有一个 DTO 作为过滤器,在控制器中用于进行过滤。
public class Controller {
private final int BUTTONS_TO_SHOW = 5;
public String home(FilterDTO filterDTO @PageableDefault(size = 50) Pageable pageable, Model model){
List<YourEntity> rows = YourEntityService.findAll();
Pager pager = new Pager(rows.getTotalPages(), rows.getNumber(), BUTTONS_TO_SHOW);
model.addAttribute("rows", rows);
model.addAttribute("pager", pager);
model.addAttribute("filterDTO", filterDTO);
return "your-template";
}
}
分页器是这样的:
<nav style="display: inline-block">
<ul class="pagination">
<li th:class="page-item" th:classappend="${rows.number == 0} ? ''">
<a class="page-link" th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=0)}">«</a>
</li>
<li th:class="page-item" th:classappend="${rows.number == 0} ? ''">
<a class="page-link" th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${rows.number - 1})}">←</a>
</li>
<li th:class="page-item" th:classappend="${rows.number == (page - 1)} ? 'active pointer-disabled'"
th:each="page : ${#numbers.sequence(pager.startPage, pager.endPage)}">
<a class="page-link" th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${page - 1})}" th:if="${page != 0}"
th:text="${page}"></a>
</li>
<li th:class="page-item" th:classappend="${rows.number + 1 == rows.totalPages or pager.endPage == 0} ? ''">
<a class="page-link"
th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${rows.number + 1})}">→</a>
</li>
<li th:class="page-item" th:classappend="${rows.number + 1 == rows.totalPages or pager.endPage == 0} ? ''">
<a class="page-link"
th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${rows.totalPages - 1})}">»</a>
</li>
</ul>
</nav>
在 FilterDTO class 中,我实现了方法:toQueryString()
returns 查询字符串与您应用的过滤器。
在我的许多页面上,我有几个选项可以对一长串结果进行排序或过滤。
我希望在有人翻阅数据时正确保留这些选择。例如:
- 开始查看所有工单的列表。 (
/tickets
) - 搜索所有类似 "foo." (
/tickets?query=foo
) 的门票
- 转到下一页。 (
/tickets?query=foo&page=2
) - 请参阅 "foo" 等门票的下一页,而不是 "all tickets." 的第二页(例如,不是
/tickets?page=2
)
在JSP中,我想到了这样的解决方案:
<c:if test="${page.hasNext()}">
<spring:url value="" var="nextLink">
<c:forEach items="${param}" var="curParam">
<c:if test="${curParam.key != 'page'}">
<spring:param name="${curParam.key}" value="${curParam.value}"/>
</c:if>
</c:forEach>
<spring:param name="page" value="${page.nextPageable().pageNumber}"/>
</spring:url>
<li>
<a href="${nextLink}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</c:if>
这基本上构造了一个新的 URL 指向与当前页面相同的路径,但是 adds/replaces 它的查询参数的 "path" 参数。
它在 JSP 中非常丑陋,但我在 Thymeleaf 中完全看不到真正做到这一点的方法?
或者,也许有一些更好的方法可以使用一些我还没有遇到过的 Spring 或 Thymeleaf 功能来做到这一点?
我希望有一个简洁的 Thymeleaf 片段,我可以在需要分页的任何地方重复使用。到目前为止,这就是我所拥有的,但它最终缺少 "query" 参数等。(我不想在这里对查询参数进行硬编码,因为这会限制此分页代码的可重用性)
<li th:if="${page.hasNext()}">
<a href="pagination.html" th:href="@{''(page=${page.nextPageable().pageNumber})}" aria-label="next">
<span aria-hidden="true">»</span>
</a>
</li>
Dandelion Datatables 是一个可以帮助您避免重新发明轮子的项目。 http://dandelion.github.io/components/datatables/
也许这对将 HTML 和 Spring 与 Thymeleaf 一起使用的人有用。
在我的例子中,我将 thymeleaf 与 spring 一起使用。我有一个 DTO 作为过滤器,在控制器中用于进行过滤。
public class Controller {
private final int BUTTONS_TO_SHOW = 5;
public String home(FilterDTO filterDTO @PageableDefault(size = 50) Pageable pageable, Model model){
List<YourEntity> rows = YourEntityService.findAll();
Pager pager = new Pager(rows.getTotalPages(), rows.getNumber(), BUTTONS_TO_SHOW);
model.addAttribute("rows", rows);
model.addAttribute("pager", pager);
model.addAttribute("filterDTO", filterDTO);
return "your-template";
}
}
分页器是这样的:
<nav style="display: inline-block">
<ul class="pagination">
<li th:class="page-item" th:classappend="${rows.number == 0} ? ''">
<a class="page-link" th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=0)}">«</a>
</li>
<li th:class="page-item" th:classappend="${rows.number == 0} ? ''">
<a class="page-link" th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${rows.number - 1})}">←</a>
</li>
<li th:class="page-item" th:classappend="${rows.number == (page - 1)} ? 'active pointer-disabled'"
th:each="page : ${#numbers.sequence(pager.startPage, pager.endPage)}">
<a class="page-link" th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${page - 1})}" th:if="${page != 0}"
th:text="${page}"></a>
</li>
<li th:class="page-item" th:classappend="${rows.number + 1 == rows.totalPages or pager.endPage == 0} ? ''">
<a class="page-link"
th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${rows.number + 1})}">→</a>
</li>
<li th:class="page-item" th:classappend="${rows.number + 1 == rows.totalPages or pager.endPage == 0} ? ''">
<a class="page-link"
th:href="@{${#httpServletRequest.requestURI+'?'+filterDTO.toQueryString()}(page=${rows.totalPages - 1})}">»</a>
</li>
</ul>
</nav>
在 FilterDTO class 中,我实现了方法:toQueryString()
returns 查询字符串与您应用的过滤器。