Pagination Angular With Gem Kaminari
Mình mới làm quen với angular 1 thời gian, phải sử lý đến pagination. :man_detective_tone1: Những thư viện của angular đều là load tất cả item vào pagination rồi xử lý, nên mình quyết định custom 1 cái service pagination dùng cho sướng .. Làm với gem Kaminari chỉ cần truyền lên params[:page] ...
Mình mới làm quen với angular 1 thời gian, phải sử lý đến pagination. :man_detective_tone1:
Những thư viện của angular đều là load tất cả item vào pagination rồi xử lý, nên mình quyết định custom 1 cái service pagination dùng cho sướng ..
Làm với gem Kaminari chỉ cần truyền lên params[:page] nên mình sẽ làm service bên angular phù hợp với nhu cầu của mình :D
Đầu tiên sẽ tạo 1 component tạo view và sử lý chung: pagination.component.ts
@Component({
selector: 'app-pagination',
templateUrl: 'pagination.component.html',
styleUrls: ['pagination.component.scss']
})
Trong view: pagination.component.html*
<ul *ngFor="let page of pages" class="pagination"> <li (click)="selectPagination(page)">{{ page }}</li> </ul>
Xây tạm xong phần view của pagination
Bây giờ sẽ sang phần service của paginate
getPagesInPaginate(pages, currentPage: number = 1,
pageDistance: number = valSetting.DEFAULT_PAGE_DISTANCE,
pageSize: number = valSetting.DEFAULT_PAGE_SIZE) {
const listPages = [];
const totalPages: number = Math.ceil(pages / pageSize);
let startPage: number, endPage: number;
if (totalPages < 2 * pageDistance) {
startPage = 1;
endPage = totalPages;
} else {
if (currentPage <= pageDistance) {
startPage = 1;
endPage = 2 * pageDistance + 1;
} else if (currentPage + pageDistance > totalPages) {
startPage = totalPages - 2 * pageDistance;
endPage = totalPages;
} else {
startPage = currentPage - pageDistance;
endPage = currentPage + pageDistance;
}
}
for (let i = startPage ; i <= endPage; i++) {
listPages.push(i);
}
method này trong service sẽ trả ra 1 Array có số thứ tự của page( trên view sẽ lấy ra Array này để hiển thị pagination )
(VD ở đây có pageDistance = 5 )
[1] 2 3 4 5 6 7 8 9 10
1 [2] 3 4 5 6 7 8 9 10
1 2 [3] 4 5 6 7 8 9 10
1 2 3 [4] 5 6 7 8 9 10
1 2 3 4 [5] 6 7 8 9 10
1 2 3 4 5 [6] 7 8 9 10
2 3 4 5 6 [7] 8 9 10 11
3 4 5 6 7 [8] 9 10 11 12
4 5 6 7 8 [9] 10 11 12 13
5 6 7 8 9 [10] 11 12 13 14
6 7 8 9 10 [11] 12 13 14 15
6 7 8 9 10 11 [12] 13 14 15
6 7 8 9 10 11 12 [13] 14 15
6 7 8 9 10 11 12 13 [14] 15
6 7 8 9 10 11 12 13 14 [15]
Ở đây ta sử dụng Samples Component đế sử dụng service pagination
Có 1 vấn đề là khi Samples truyền record.size để build pagination thì nó đã được build xong với pages = [ ], nên ta phải có sự kiện luôn lắng nghe khi pagination service trả lại số lượng pages
// Pagination.component.ts this.paginationService.getPages.subscribe(pages => { this.pages = pages; });
Để sử dụng:
** Tạo 1 Samples.component
import pagination.service**
//Samples.component.ts import { PaginationService } from '../services/pagination.service';
** Add pagination.component vào declarations và exports trong module để sử dụng**
Trong view Samples gọi seletor của pagination
//Samples.component.html <app-pagination></app-pagination>
** Truyền record size vào pagination.service là xong :D**
//Samples.component constructor(private paginationService: PaginationService) { } this.paginationService.getPagesInPaginate(totalPages);
** Vậy là đã hiển thị xong pagination**
** Bây giờ là event khi clicked
Ta sẽ cần 1 sự kiện lắng nghe mỗi khi pagination được clicked tại pagination.service**
this.paginationService.getCurrentPages.subscribe(currentPage => {
//To do ...
});
** Ta có thể lấy được pages mà vừa được click, truyền lên sever để lấy lại item mới :D **
Bonus:
Mình có sinh ra các nút go first page or go last page, các bạn có thể sử dụng or custom lại
Vấn đề khi sử dụng pagination + selec , mình có giải quyết bằng 1 hàm reset current pages trong service, mỗi khi select xong nó sẽ để current_page đúng giá trị mong muốn
this.paginationService.resetCurrenPage(:number);
Các bạn có thể xem full tại đây:
https://github.com/vuhuutuan262/angular_pagination_with_kaminari