10
respostas

Componente para paginação em angular 6

Tenho este componente que tenho que repetir em todos que precisa de uma paginação, assim duplicando códigos.

Código HTML

<mat-card-content *ngIf="mostrarPesquisa">
            <div class="mat-paginator-outer-container" style="align-content: left">
              <div class="mat-paginator-container">
                <div class="mat-paginator-range-actions">
                  <div class="mat-paginator-range-label">Página <b>{{paginaAtual}}</b> de <b>{{totalPagina}}</b> - 
                    Total de Registros: <b>{{totalRegistros}}</b>

                    <button class="mat-paginator-navigation-previous mat-icon-button" mat-icon-button="" 
                      type="button" aria-describedby="cdk-describedby-message-25" cdk-describedby-host="" 
                      matTooltip="Primeira página" style="touch-action: none; user-select: none; 
                      -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"
                      (click)="paginaAnterior()">
                      <span class="mat-button-wrapper">
                        <mat-icon>first_page</mat-icon>
                      </span>
                      <div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple=""></div>
                      <div class="mat-button-focus-overlay"></div>
                    </button>

                    <button class="mat-paginator-navigation-previous mat-icon-button" mat-icon-button="" 
                      type="button" aria-describedby="cdk-describedby-message-25" cdk-describedby-host="" 
                      matTooltip="Página anterior" style="touch-action: none; user-select: none; 
                      -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"
                      (click)="paginaAnterior()">
                      <span class="mat-button-wrapper">
                        <mat-icon>chevron_left</mat-icon>
                      </span>
                      <div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple=""></div>
                      <div class="mat-button-focus-overlay"></div>
                    </button>

                    <button class="mat-paginator-navigation-next mat-icon-button" mat-icon-button="" type="button" 
                      aria-describedby="cdk-describedby-message-26" cdk-describedby-host="" 
                      matTooltip="Próxima página" matTooltipPosition="below" 
                      style="touch-action: none; user-select: none; -webkit-user-drag: none; 
                      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"
                      (click)="proximaPagina()">
                      <span class="mat-button-wrapper">
                        <mat-icon>chevron_right</mat-icon>
                      </span>
                      <div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple=""></div>
                      <div class="mat-button-focus-overlay"></div>
                    </button>

                    <button class="mat-paginator-navigation-next mat-icon-button" mat-icon-button="" type="button" 
                      aria-describedby="cdk-describedby-message-26" cdk-describedby-host="" 
                      matTooltip="Última página" matTooltipPosition="below" 
                      style="touch-action: none; user-select: none; -webkit-user-drag: none; 
                      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"
                      (click)="proximaPagina()">
                      <span class="mat-button-wrapper">
                        <mat-icon>last_page</mat-icon>
                      </span>
                      <div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple=""></div>
                      <div class="mat-button-focus-overlay"></div>
                    </button>


                  </div>
                </div>
              </div>
            </div>
          </mat-card-content>
10 respostas

Código TS, que todos extends:

       public paginaAnterior() {
         this.modelo.paginaAtual = this.paginaAtual - 1;
         if (this.modelo.paginaAtual !== 0 && this.modelo.paginaAtual <= this.paginaAtual) {
           this.pesquisar(false);
         }
       }

       public proximaPagina() {
         this.modelo.paginaAtual = this.paginaAtual + 1;
         if (this.paginaAtual < this.totalPagina) {
           this.pesquisar(false);
         }
       }

Criei um componente com o nome paginacao, e assim em todos os htmls, informei a tag < app-paginacao></ app-paginacao>, mostrando o html. Mas sem ação.

Criei um service, para fazer funcionar as ações, mas não consegui. Segue o código: ` export class PaginacaoService {

   public modelo = new EventEmitter<any>();

   public primeiraPagina = new EventEmitter<any>();
   public paginaAnterior = new EventEmitter<any>();
   public proximaPagina = new EventEmitter<any>();
   public ultimaPagina = new EventEmitter<any>();
   public paginaAtual = new EventEmitter<any>();
   public totalPagina = new EventEmitter<any>();
   public totalRegistros = new EventEmitter<any>();

   public modeloFormulario(modelo: any) {
     this.modelo.emit(modelo);
   }

   public primeiraPaginaFormulario() {
     this.primeiraPagina.emit();
   }

   public paginaAnteriorFormulario() {
     this.paginaAnterior.emit();
   }

   public proximaPaginaFormulario() {
     this.proximaPagina.emit();
   }

   public ultimaPaginaFormulario() {
     this.ultimaPagina.emit();
   }

   public paginaAtualFormulario() {
     this.paginaAtual.emit();
   }

   public totalPaginaFormulario() {
     this.totalPagina.emit();
   }

   public totalRegistrosFormulario() {
     this.totalRegistros.emit();
   }

O que está faltando ?

Fala aí Guilherme, tudo bem? Já chegou a dar uma olhada no {Angular Material](https://material.angular.io)? Lá tem um componente para tabelas onde o mesmo possui sistema de paginação.

Talvez não precise reinventar e implementar um do zero (vai exigir um certo trabalho).

Veja se é possível usar algum pronto, caso não seja, a gente dá um jeito de arrumar o seu.

Espero ter ajudado.

Opa. Sim, analisei ela sim. E muita por sinal.

A questão não é reinventar, mas como não expliquei melhor o que quero né.

É porque quero que a paginação seja por demanda. Exemplo não buscar em uma tabela 100 registros de uma vez, mas de 10 em 10.

Ai entendi que este componente de paginação não faz.

Entendi, tinha entendido errado mesmo.

Para esse problema, você precisa que a API realize a paginação, a ideia seria você passar algum parâmetro informando a página que pretende e quantos itens por página, por exemplo:

/clientes?pagina=1&quantidadePorPagina=10

Algo nesse caminho, dai no front assim que trocar a página, você chama a API novamente porém mudando a pagina (incrementando ou diminuindo).

A ideia é salvar a página atual e em caso de próxima página, chame a atual + 1, se for a anterior, faça a atual - 1.

Também pode fazer um loop para construir a paginação, onde pode clicar diretamente na 4 ou 5, por exemplo.

Espero ter ajudado.

Tenho uma classe no servidor, que recebe a paginação, qtd de registros por página, total no banco de dados. E um model que recebe as informações do servidor.

Funciona normalmente, mas tenho que reconstruir todo o HTML nas páginas que utilizam.

A idéia é reutilização do código por um component no angular e chamar assim < app-paginacao>< /app-paginacao>. Fazendo assim o html é montado, mas tenho que acessar um serviço no angular, que passa as informações para o servidor e retorna. Assim cada página é um modelo no angular.

Estou fazendo assim:

paginacao.service.ts

import { Injectable, EventEmitter } from '@angular/core';

    @Injectable({
      providedIn: 'root'
    })
    export class PaginacaoService {

      public static modelo = new EventEmitter<any>();
      public static primeiraPagina = new EventEmitter<any>();
      public static paginaAnterior = new EventEmitter<any>();
      public static proximaPagina = new EventEmitter<any>();
      public static ultimaPagina = new EventEmitter<any>();
      public static paginaAtual = new EventEmitter<any>();
      public static totalPagina = new EventEmitter<any>();
      public static totalRegistros = new EventEmitter<any>();
    }

paginacao.component.ts

 import { Component, OnInit } from '@angular/core';

    import { PaginacaoService } from '../../../service/paginacao/paginacao.service';

    @Component({
      selector: 'app-paginacao',
      templateUrl: './paginacao.component.html',
      styleUrls: ['./paginacao.component.css']
    })
    export class PaginacaoComponent implements OnInit {

      /**
       * variáveis de paginação
       */
      public totalPagina: number;
      public totalRegistros: number;
      public paginaAtual: number;

      public modelo: any;

      constructor(
        protected paginacaoService: PaginacaoService
      ) {}

      ngOnInit() {
        this.preencherVariaveisComponente();
      }

      private preencherVariaveisComponente() {
        PaginacaoService.paginaAtual.subscribe(
          paginaAtual => {
            this.paginaAtual = paginaAtual;
          }
        );
      }
    }

paginacao.component.html

 Página <b>{{paginaAtual}}</b> de <b>{{totalPagina}}</b> - 
              Total de Registros: <b>{{totalRegistros}}</b>

A variável nunca é atualizada, mesmo o serviço trazer o valor, conforme imagem:

Se preencho valor assim:

    this.paginaAtual = 1;
        PaginacaoService.paginaAtual.subscribe(
          paginaAtual => {
            this.paginaAtual = paginaAtual;
          }
        );

Funciona, mas se o valor vier pelo servico, conforme imagem, não funciona. O que pode ser ?

Fala aí, tudo bem? Eu faria um pouco diferente.

Criaria três @Output property, um para próxima página, página anterior e página X.

Assim que cada clique no componente fosse feito, eu emitira o evento para o pai através do .emit e como parâmetro passaria o número da página.

Dai no pai, teria uma função que iria ouvir todas essas três, simplesmente iria pegar a página que chegou e mandar buscá-la na API.

Mais ou menos essa a ideia.

Espero ter ajudado.

Obrigado Matheus, mas não entendi.

Poderia me ajudar com um exemplo ?

Fala aí Guilherme, segue o exemplo:

https://codesandbox.io/s/vj2o36okpl

Desculpa a demora, estava bem corrido por aqui.

Espero ter ajudado.