javascript
使用Spring数据和Thymeleaf实现Bootstrap分页
Twitter Bootstrap具有非常好的分頁UI ,在這里我將向您展示如何使用Spring Data Web分頁功能和Thymeleaf條件評估功能來實現它。
引導程序中的標準分頁
受Rdio啟發的簡單分頁,非常適合應用程序和搜索結果。 大塊很難錯過,易于擴展,并提供較大的點擊區域。
從Bootstrap文檔顯示分頁的原始源代碼非常簡單:
<div class='pagination'><ul><li><a href='#'>Prev</a></li><li><a href='#'>1</a></li><li><a href='#'>2</a></li><li><a href='#'>3</a></li><li><a href='#'>4</a></li><li><a href='#'>5</a></li><li><a href='#'>Next</a></li></ul> </div>您可以看到這只是一個模擬代碼,要使其通過正確的超鏈接URL動態顯示頁碼,我需要對現有代碼進行很多更改。 因此,讓我們從頭開始,先更改域層,然后再更改應用程序服務層,表示層。 最后是將它們粘合在一起的配置。
域層更改
域層的唯一更改是BlogPostRepository 。 在具有檢索按publishedTime排序的publishedTime發布BlogPost列表的方法之前:
public interface BlogPostRepository extends MongoRepository<BlogPost, String>{ ...List<BlogPost> findByPublishedIsTrueOrderByPublishedTimeDesc(); ... }現在我們需要獲取分頁結果列表。 使用Spring Data Page ,我們將返回Page<BlogPost>而不是List<BlogPost> ,并傳遞Pageable參數:
public interface BlogPostRepository extends MongoRepository<BlogPost, String>{ ...Page<BlogPost> findByPublishedIsTrueOrderByPublishedTimeDesc(Pageable pageable); ... }應用程序服務層更改:
只需使用BlogPostRepository新功能,應用程序服務層的更改也非常簡單:
BlogService界面
public interface BlogService { ...Page<BlogPost> getAllPublishedPosts(Pageable pageable); ... }BlogServiceImpl類
public class BlogServiceImpl implements BlogService { ...private final BlogPostRepository blogPostRepository; ...@Overridepublic Page<BlogPost> getAllPublishedPosts(Pageable pageable) {Page<BlogPost> blogList = blogPostRepository.findByPublishedIsTrueOrderByPublishedTimeDesc(pageable);return blogList;} ... }表示層更改:
Spring Data Page界面具有許多不錯的功能來獲取當前頁碼,獲取總頁數等。但是仍然缺少讓我僅顯示總分頁的部分頁面范圍的方法。 因此,我創建了一個適配器類,以使用其他功能包裝Sprng數據頁面接口。
public class PageWrapper<T> {public static final int MAX_PAGE_ITEM_DISPLAY = 5;private Page<T> page;private List<PageItem> items;private int currentNumber;private String url;public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public PageWrapper(Page<T> page, String url){this.page = page;this.url = url;items = new ArrayList<PageItem>();currentNumber = page.getNumber() + 1; //start from 1 to match page.pageint start, size;if (page.getTotalPages() <= MAX_PAGE_ITEM_DISPLAY){start = 1;size = page.getTotalPages();} else {if (currentNumber <= MAX_PAGE_ITEM_DISPLAY - MAX_PAGE_ITEM_DISPLAY/2){start = 1;size = MAX_PAGE_ITEM_DISPLAY;} else if (currentNumber >= page.getTotalPages() - MAX_PAGE_ITEM_DISPLAY/2){start = page.getTotalPages() - MAX_PAGE_ITEM_DISPLAY + 1;size = MAX_PAGE_ITEM_DISPLAY;} else {start = currentNumber - MAX_PAGE_ITEM_DISPLAY/2;size = MAX_PAGE_ITEM_DISPLAY;}}for (int i = 0; i<size; i++){items.add(new PageItem(start+i, (start+i)==currentNumber));}}public List<PageItem> getItems(){return items;}public int getNumber(){return currentNumber;}public List<T> getContent(){return page.getContent();}public int getSize(){return page.getSize();}public int getTotalPages(){return page.getTotalPages();}public boolean isFirstPage(){return page.isFirstPage();}public boolean isLastPage(){return page.isLastPage();}public boolean isHasPreviousPage(){return page.hasPreviousPage();}public boolean isHasNextPage(){return page.hasNextPage();}public class PageItem {private int number;private boolean current;public PageItem(int number, boolean current){this.number = number;this.current = current;}public int getNumber(){return this.number;}public boolean isCurrent(){return this.current;}} }使用此PageWrapper ,我們可以包裝從BlogService返回的Page<BlogPost>并將其放入SpringMVC UI模型。 請參閱博客頁面的控制器代碼:
@Controller public class BlogController ...@RequestMapping(value = '/blog', method = RequestMethod.GET)public String blog(Model uiModel, Pageable pageable) {PageWrapper<BlogPost> page = new PageWrapper<BlogPost>(blogService.getAllPublishedPosts(pageable), '/blog');uiModel.addAttribute('page', page);return 'blog';} ... }Pageable是從PageableArgumentResolver傳入的,我將在后面解釋。 另一個技巧是我還將視圖URL傳遞給PageWrapper ,它可用于在分頁欄中構造Thymeleaf超鏈接。
由于我的PageWrapper非常通用,因此我為分頁欄創建了一個html片段,因此當需要分頁時,可以將其用于應用程序頁面中的任何位置。 該片段html使用Thymeleaf th:if根據鏈接是否被禁用來在靜態文本或超鏈接之間動態切換。 并且它使用th:href構造具有正確頁碼和頁面大小的URL。
<!-- Pagination Bar --> <div th:fragment='paginationbar'><div class='pagination pagination-centered'><ul><li th:class='${page.firstPage}? 'disabled' : '''><span th:if='${page.firstPage}'>← First</span><a th:if='${not page.firstPage}' th:href='@{${page.url}(page.page=1,page.size=${page.size})}'>← First</a></li><li th:class='${page.hasPreviousPage}? '' : 'disabled''><span th:if='${not page.hasPreviousPage}'>?</span><a th:if='${page.hasPreviousPage}' th:href='@{${page.url}(page.page=${page.number-1},page.size=${page.size})}' title='Go to previous page'>?</a></li><li th:each='item : ${page.items}' th:class='${item.current}? 'active' : '''><span th:if='${item.current}' th:text='${item.number}'>1</span><a th:if='${not item.current}' th:href='@{${page.url}(page.page=${item.number},page.size=${page.size})}'><span th:text='${item.number}'>1</span></a></li><li th:class='${page.hasNextPage}? '' : 'disabled''><span th:if='${not page.hasNextPage}'>?</span><a th:if='${page.hasNextPage}' th:href='@{${page.url}(page.page=${page.number+1},page.size=${page.size})}' title='Go to next page'>?</a></li><li th:class='${page.lastPage}? 'disabled' : '''><span th:if='${page.lastPage}'>Last →</span><a th:if='${not page.lastPage}' th:href='@{${page.url}(page.page=${page.totalPages},page.size=${page.size})}'>Last →</a></li></ul></div> </div>Spring配置變更
最后一步是將它們放在一起。 幸運的是,在更新代碼之前,我做了一些研究。 Doug Haber 撰寫了一篇非常不錯的博客文章, 其中介紹了Spring MVC,Spring Data和Java Config 。 Doug在他的博客中提到了一些陷阱,尤其是Pageable參數需要一些配置技巧:
為了讓Spring知道如何將參數轉換為Pageable對象,您需要配置HandlerMethodArgumentResolver。 Spring Data提供了一個PageableArgumentResolver,但是它使用了舊的ArgumentResolver接口,而不是新的(Spring 3.1)HandlerMethodArgumentResolver接口。 XML config可以為我們解決這種差異,但是由于我們使用的是Java Config,因此我們必須手動進行一些操作。 幸運的是,如果您知道正確的魔術咒語,就可以輕松解決此問題……
道格·哈伯(Doug Haber)
在Doug的幫助下,我將此參數解析器添加到了WebConfig類中:
@Configuration @EnableWebMvc @ComponentScan(basePackages = 'com.jiwhiz.blog.web') public class WebConfig extends WebMvcConfigurerAdapter { ...@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {PageableArgumentResolver resolver = new PageableArgumentResolver();resolver.setFallbackPagable(new PageRequest(1, 5));argumentResolvers.add(new ServletWebArgumentResolverAdapter(resolver));} ... } 完成所有這些更改后,我的博客列表的頁面頂部和底部將具有分頁欄,并且它始終最多具有5個頁碼,中間??是當前編號,并且已禁用。 分頁欄還具有第一和開頭以前的鏈接, 然后在年底最后環節。 我還在管理頁面,用戶列表和評論列表中使用了它,并且效果很好。
參考:來自Jiwhiz博客的JCG合作伙伴 Yuan Ji的Spring Data和Thymeleaf實現Bootstrap分頁 。
翻譯自: https://www.javacodegeeks.com/2013/03/implement-bootstrap-pagination-with-spring-data-and-thymeleaf.html
總結
以上是生活随笔為你收集整理的使用Spring数据和Thymeleaf实现Bootstrap分页的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 功能接口简介–在Java 8中重新创建的
- 下一篇: 如何在Word中打勾电脑上如何打勾