2
I am with a system where all modules have a standardized record listing screen with pagination. I adapted a pagination code I found on the Internet to make pagination on demand. However, instead of repeating this code on all listing screens I would like to create a component to just be called on these screens. I do it this way:
Adapted Service that makes the pagination
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class PagerService {
getPager(totalItems: number, currentPage: number = 0, pageSize: number = 10) {
// calculate total pages
let totalPages = Math.ceil(totalItems / pageSize);
// ensure current page isn't out of range
if (currentPage < 0) {
currentPage = 0;
} else if (currentPage > totalPages) {
currentPage = totalPages;
}
let startPage: number, endPage: number;
if (totalPages <= 10) {
// less than 10 total pages so show all
startPage = 1;
endPage = totalPages;
} else {
// more than 10 total pages so calculate start and end pages
if (currentPage <= 5) {
startPage = 1;
endPage = 10;
} else if (currentPage + 3 >= totalPages) {
startPage = totalPages - 9;
endPage = totalPages;
} else {
startPage = currentPage - 4;
endPage = currentPage + 3;
}
}
// calculate start and end item indexes
let startIndex = (currentPage) * pageSize;
let endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);
// create an array of pages to ng-repeat in the pager control
let pages = Array.from(Array((endPage + 1) - startPage).keys()).map(i => startPage + i);
// return object with all pager properties required by the view
return {
totalItems: totalItems,
currentPage: currentPage,
pageSize: pageSize,
totalPages: totalPages,
startPage: startPage,
endPage: endPage,
startIndex: startIndex,
endIndex: endIndex,
pages: pages
};
}
}
Listing Component
import { AppSettings } from './../../settings/app-settings';
import { PageEquipamento } from './../entity/page-equipamento';
import { Component, OnInit } from '@angular/core';
import AppHelper from '../../helper/AppHelper';
import { LoadingHugeComponent } from '../../loading/huge/loading-huge.component';
import { Title } from '@angular/platform-browser';
import { SharedDataService } from '../../services/SharedDataService';
import { Router, ActivatedRoute } from '@angular/router';
import { EquipamentosService } from '../services/equipamentos.service';
import { ToastrService } from 'ngx-toastr';
import { environment } from '../../../environments/environment';
import { Equipamento } from '../../entity/equipamento';
import { PagerService } from '../../services/pager.service';
import { Observable, of } from 'rxjs';
declare var $: any;
@Component({
selector: 'app-listar-equipamentos',
templateUrl: './listar-equipamentos.component.html',
styleUrls: ['./listar-equipamentos.component.css'],
preserveWhitespaces: true
})
export class ListarEquipamentosComponent implements OnInit {
//Rotas
private appHelper: AppHelper = new AppHelper();
public loadingHugeComponent = LoadingHugeComponent;
public listUrls;
//Equipamento Selecionado
public indexEquipamentoSelecionado: number;
public nomeSelecionado: string;
//Paginação
pager: any = {};
pagedItems: any[];
//Page Equipamentos
private subPageEquipamento;
public pageEquipamento: PageEquipamento = new PageEquipamento();
constructor(private titleService: Title, private sharedDataService: SharedDataService,
private router: Router,
private route: ActivatedRoute,
private equipamentosService: EquipamentosService,
private toastrService: ToastrService,
private pagerService: PagerService
) {
const allowed = ['listarEquipamentos', 'gravarEquipamento'];
this.listUrls = this.appHelper.urlNotAllowed(allowed, environment.urls);
}
ngOnInit() {
this.loadRegistrosPaginados();
}
ngOnDestroy() {
this.subPageEquipamento.unsubscribe();
}
confirmaExcluirEquipamento(i: number) {
this.indexEquipamentoSelecionado = i;
this.nomeSelecionado = this.pageEquipamento.listaEquipamentos[i].nome;
$('#modalLista').modal('show');
}
excluirEquipamento() {
setTimeout(() => {
this.equipamentosService.excluirEquipamento(this.pageEquipamento.listaEquipamentos[this.indexEquipamentoSelecionado].id).subscribe(
resp => {
this.toastrService.info(this.pageEquipamento.listaEquipamentos[this.indexEquipamentoSelecionado].nome, ' Excluido com sucesso!');
this.pageEquipamento.listaEquipamentos.splice(this.indexEquipamentoSelecionado, 1);
this.loadRegistrosPaginados();
}, error => {
this.toastrService.error('Não foi possível excluir');
}
);
}, 900);
}
//Carrega os registros paginados
loadRegistrosPaginados() {
this.subPageEquipamento = this.equipamentosService.getEquipamentosPage(AppSettings.RESGISTROS_POR_PAGINA)
.subscribe(resp => {
this.pageEquipamento.listaEquipamentos = resp.content;
this.pageEquipamento.totalElements = resp.totalElements;
//Gera o HTML da Paginação
this.pager = this.pagerService.getPager(this.pageEquipamento.totalElements, 1, AppSettings.RESGISTROS_POR_PAGINA);
this.pagedItems = this.pageEquipamento.listaEquipamentos.slice(this.pager.startIndex, this.pager.endIndex + 1);
});
}
//Método chamado pela paginação
setPage(page: number) {
this.subPageEquipamento = this.equipamentosService.getEquipamentosPage(AppSettings.RESGISTROS_POR_PAGINA, page - 1)
.subscribe(resp => {
this.pageEquipamento.listaEquipamentos = resp.content;
this.pageEquipamento.totalElements = resp.totalElements
});
this.pager = this.pagerService.getPager(this.pageEquipamento.totalElements, page, AppSettings.RESGISTROS_POR_PAGINA);
this.pagedItems = this.pageEquipamento.listaEquipamentos.slice(this.pager.startIndex, this.pager.endIndex + 1);
}
}
HTML of the Pagination
<!--Paginação-->
<div *ngIf="!(pageProposta.listaEquipamentos?.length===0)">
<div class="container">
<div class="text-center">
<!-- items being paged -->
<div *ngFor="let item of pagedItems">{{item.name}}</div>
<!-- pager -->
<ul *ngIf="pager.pages && pager.pages.length" class="pagination">
<li [ngClass]="{disabled:pager.currentPage === 1}">
<a [routerLink]="" (click)="setPage(1)">Primeiro</a>
</li>
<li *ngFor="let page of pager.pages" [ngClass]="{active:pager.currentPage === page}">
<a [routerLink]="" (click)="setPage(page)">{{page}}</a>
</li>
<li [ngClass]="{disabled:pager.currentPage === pager.totalPages}">
<a [routerLink]="" (click)="setPage(pager.totalPages)">Último</a>
</li>
</ul>
</div>
</div>
</div>
Using this logic it is possible to adapt it to create a reusable component for all system listing screens?
Thank you
you just add the <app-list-equipment></app-list-equipment> tag where you want to use this component of yours
– Eduardo Vargas
You want to compose the
pager
?– Victor Henrique
If you want a componentized table take a look at my example: https://stackblitz.com/edit/tabela-html?file=src%2Fapp%2Fapp.component.html I created a table that can be reused in a very simple way using ng-template and vc can adapt to leave with paging and item deletion control and everything else...
– Jonathan Santos
The problem I’m having is with the subscribe inside the setPage() method, because when this method is called by HTML I reload the equipment list (this.pageEquipment.listsEquipments) if I put this method in the separate component I won’t be able to reload it...
– Andre