Angular 7 - Filtro, Ordenação e Paginação - Web API 2


  Hoje veremos realizar aplicar filtro, ordenação e paginação de dados no Angular 6/7 acessando dados de uma Web API ASP .NET MVC 5.

A paginação permite que as informações sejam divididas entre páginas; o objetivo é evitar apresentar em uma única página uma grande quantidade de dados, o que pode ser difícil de tratar e também pode impactar o desempenho do seu projeto.

Vamos realizar a paginação de dados obtidos a partir de uma WEB API ASP .NET MVC que foi criada neste artigo: Angular 7 - Consumindo Web API ASP .NET MVC - I

Abaixo vemos o banco de dados Estudo e a tabela Clientes com os dados que iremos filtrar, ordenar e paginar:

Criando um aplicação Angular

Vamos usar o Angular CLI para criar nossa aplicação Angular que vai paginar dados.

Nota: Para verificar a versão do seu Angular CLI digite: ng --version  

O comando : npm install -g @angular/cli   instala o Angular CLI.

Vamos criar a aplicação angular em uma pasta reservada para projetos angular: c:\_angular_2019

Aabra uma prompt de comandos, entre na pasta do projeto e a seguir e digite o comando : ng new ngclientes

Será criado um projeto Angular na pasta ngclientes. Vamos entrar na pasta digitando:  cd ngclientes

Vamos criar um componente Cliente em nosso projeto Angular.

Estando na pasta do projeto digite o comando : ng g c cliente --spec=false

Este comando vai criar a pasta cliente dentro da pasta app, e, dentro da pasta cliente serão criados os arquivos:

Além de criar estes arquivos o Angular CLI atualiza o arquivo app.module.ts com as referências aos componentes criados.

Agora, ainda estando na pasta do projeto, vamos criar um serviço na raiz da pasta app.

Para isso digite o comando: ng g s cliente --spec=false

O arquivo cliente.service.ts é onde vamos definir o serviço que vai acessar a nossa Web API.

A seguir vamos criar a classe Cliente na raiz da pasta app.

Para isso digite o comando :  ng g class cliente

O arquivo cliente.ts é onde vamos definir a classe Cliente usando o Visual Studio Code.

Vamos então abrir o arquivo cliente.ts no VS Code e incluir o código abaixo neste arquivo:

export class Cliente {
    id: string;
    nome: string;
    endereco: string;
    telefone: string;
    email: string;
    cidade: string;
}

Criando o serviço

A seguir vamos abrir o arquivo cliente.service.ts e definir o código a seguir:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';  
import { HttpHeaders } from '@angular/common/http';  
import { Observable } from 'rxjs';  
import { Cliente } from './cliente'; 
var httpOptions = {headers: new HttpHeaders({"Content-Type": "application/json"})};
@Injectable({
  providedIn: 'root'
})
export class ClienteService { 
  url = 'http://localhost:16434/api/clientes';  
  constructor(private http: HttpClient) { }
  getAllCliente(): Observable<Cliente[]> {  
    return this.http.get<Cliente[]>(this.url + '/todos');  
  }  
  getClienteById(clienteid: string): Observable<Cliente> {  
    const apiurl = `${this.url}/${clienteid}`;
    return this.http.get<Cliente>(apiurl);  
  }  
  createCliente(cliente: Cliente): Observable<Cliente> {  
    return this.http.post<Cliente>(this.url + '/incluir', cliente, httpOptions);  
  }  
  updateCliente(clienteid: string, cliente: Cliente): Observable<Cliente> {  
    const apiurl = this.url+ '/alterar?id=' + clienteid ;
    return this.http.put<Cliente>(apiurl,cliente, httpOptions);  
  }  
  deleteClienteById(clienteid: string): Observable<number> {  
    return this.http.delete<number>(this.url + '/excluir?id=' + clienteid,httpOptions);  
  }  
}

Aqui criamos o código do serviço que usa a url de acesso a Web API e o pacote Http para definir os métodos que vão realizar as operações CRUD usando os verbos Http: get, post, put e delete:

Instalando e configurando o Angular Material

Agora vamos instalar o Angular Material em nosso projeto para criar uma interface mais amigável.

Abra uma janela de comandos e posicione-se na pasta do projeto e digite:

npm install --save @angular/material@7.3.4

npm install --save @angular/cdk@7.3.4

npm install --save @angular/animations@7.2.9

Ao final você pode abrir o arquivo package.json e conferir as versões dos pacotes instalados:

Nota: Versões diferentes poderão não funcionar corretamente.

Já temos o Angular Material referenciado, e , agora vamos criar um módulo para adicionar as referências do Material digitando o seguinte comando:

ng generate module material/angularmaterial --spec=false

A seguir abra o arquivo angularmaterial.module.ts na pasta app/material/angularmaterial e inclua o código abaixo:

import {CommonModule } from '@angular/common';
import {A11yModule} from '@angular/cdk/a11y';  
import {DragDropModule} from '@angular/cdk/drag-drop';  
import {PortalModule} from '@angular/cdk/portal';  
import {ScrollingModule} from '@angular/cdk/scrolling';  
import {CdkStepperModule} from '@angular/cdk/stepper';  
import {CdkTableModule} from '@angular/cdk/table';  
import {CdkTreeModule} from '@angular/cdk/tree';  
import {NgModule} from '@angular/core';  
import {  
  MatAutocompleteModule,  
  MatBadgeModule,  
  MatBottomSheetModule,  
  MatButtonModule,  
  MatButtonToggleModule,  
  MatCardModule,  
  MatCheckboxModule,  
  MatChipsModule,  
  MatDatepickerModule,  
  MatDialogModule,  
  MatDividerModule,  
  MatExpansionModule,  
  MatGridListModule,  
  MatIconModule,  
  MatInputModule,  
  MatListModule,  
  MatMenuModule,  
  MatNativeDateModule,  
  MatPaginatorModule,  
  MatProgressBarModule,  
  MatProgressSpinnerModule,  
  MatRadioModule,  
  MatRippleModule,  
  MatSelectModule,  
  MatSidenavModule,  
  MatSliderModule,  
  MatSlideToggleModule,  
  MatSnackBarModule,  
  MatSortModule,  
  MatStepperModule,  
  MatTableModule,  
  MatTabsModule,  
  MatToolbarModule,  
  MatTooltipModule,  
  MatTreeModule,  
} from '@angular/material';  
@NgModule({  
  exports: [  
    A11yModule,  
    CdkStepperModule,  
    CdkTableModule,  
    CdkTreeModule,  
    DragDropModule,  
    MatAutocompleteModule,  
    MatBadgeModule,  
    MatBottomSheetModule,  
    MatButtonModule,  
    MatButtonToggleModule,  
    MatCardModule,  
    MatCheckboxModule,  
    MatChipsModule,  
    MatStepperModule,  
    MatDatepickerModule,  
    MatDialogModule,  
    MatDividerModule,  
    MatExpansionModule,  
    MatGridListModule,  
    MatIconModule,  
    MatInputModule,  
    MatListModule,  
    MatMenuModule,  
    MatNativeDateModule,  
    MatPaginatorModule,  
    MatProgressBarModule,  
    MatProgressSpinnerModule,  
    MatRadioModule,  
    MatRippleModule,  
    MatSelectModule,  
    MatSidenavModule,  
    MatSliderModule,  
    MatSlideToggleModule,  
    MatSnackBarModule,  
    MatSortModule,  
    MatTableModule,  
    MatTabsModule,  
    MatToolbarModule,  
    MatTooltipModule,  
    MatTreeModule,  
    PortalModule,  
    ScrollingModule,  
  ]  
})  
export class AngularmaterialModule { }  

Agora precisamos registrar esse módulo, o serviço e o HttpClient no arquivo app.module.ts do projeto

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { ClienteComponent } from './cliente/cliente.component';
import { ClienteService } from './cliente.service';  
import { HttpClientModule } from '@angular/common/http';  
import { AngularmaterialModule } from './material/angularmaterial/angularmaterial.module'; 
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';  
@NgModule({
  declarations: [
    AppComponent,
    ClienteComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,  
    BrowserAnimationsModule,  
    AngularmaterialModule, 
    AppRoutingModule
  ],
  providers: [ClienteService],
  bootstrap: [AppComponent]
})
export class AppModule { }

 

Pronto ! já temos todas as bibliotecas registradas agora podemos definir a implementação do filtro, paginação e ordenação no projeto.

Antes vamos entender como os recursos do material serão usados para implementar essas funcionalidades apresentando as componentes que serão usados:

O componente mat-table e dataSource

Começamos inclindo o componente <table mat-table> ao nosso template e passando os dados.

A forma mais simples de passar dados para a tabela é passando um array de dados para a entrada dataSource. A tabela vai pegar o array e renderizar uma linha para cada objeto no array de dados.

Ex: <table mat-table [dataSource] = "dataSource"> ... </table>

Como a tabela otimiza o desempenho, ela não verifica se existem alterações no array de dados. Em vez disso, quando objetos são adicionados, removidos ou movidos no array de dados, podemos acionar uma atualização nas linhas renderizadas da tabela chamando o seu método renderRows().

Definindo os templates de coluna

O primeiro passo para escrever o template data-table é definir as colunas. Uma definição de coluna é especificada por meio de um <ng-container> com a diretiva matColumnDef, fornecendo um nome à coluna.

Cada definição de coluna pode conter um template header-cell(matHeaderCellDef) e um modelo data-cell (matCellDef)

Exemplo:

    <ng-container matColumnDef="Nome">  
       <th mat-header-cell *matHeaderCellDef mat-sort-header> Nome </th>  
       <td mat-cell *matCellDef="let element"> {{element.Nome}} </td>  
    </ng-container>  

O conjunto de colunas definidas representa as colunas que estão disponíveis para serem renderizadas. As colunas específicas são renderizadas em uma determinada linha, e sua ordem, são especificadas na linha.

DataSource

O DataSource destina-se a servir um local para encapsular qualquer lógica de classificação, filtragem, paginação e recuperação de dados específica para o aplicativo. Para maiss detalhes acesse este link.

Paginação

Para paginar os dados da tabela, adicione um <mat-paginator> após a tabela. O MatPaginator é uma solução fornecida para paginar os dados da sua tabela,

Classificação

Para adicionar um comportamento de classificação à tabela, adicione a diretiva matSort à tabela, que escutará automaticamente as alterações na classificação e alterará a ordem dos dados renderizados pela tabela, a seguir adicione um mat-sort-header para cada célula do cabeçalho da coluna que deve acionar a classificação. Atente que você precisa importar MatSortModule para inicializar a diretiva matSort

Filtragem

O Material angular não fornece um componente específico a ser usado para filtrar o MatTable, pois não existe uma abordagem comum para adicionar uma interface do usuário de filtro aos dados da tabela.

Uma estratégia geral é incluir uma entrada na qual os usuários possam digitar uma sequência de filtros e ouvir essa entrada para alterar quais dados são oferecidos da fonte de dados para a tabela.

Implementando a lógica do componente

Vamos agora implementar a lógica do componente para poder aplicar o filtro, a paginação e a ordenação. Para isso abra o arquivo cliente.component.ts e inclua o código:

import { Component, OnInit, ViewChild } from '@angular/core';
import { Cliente } from '../cliente';
import { MatTableDataSource, MatPaginator, MatSort } from '@angular/material';
import { ClienteService } from '../cliente.service';
@Component({
  selector: 'app-cliente',
  templateUrl: './cliente.component.html',
  styleUrls: ['./cliente.component.css']
})
export class ClienteComponent implements OnInit {
  allCliente:Cliente[];  
  dataSource: MatTableDataSource<Cliente>;  
  displayedColumns: string[] = ['ID', 'Nome', 'Email', 'Telefone','Endereco','Cidade'];  
  @ViewChild(MatPaginator) paginator: MatPaginator;  
  @ViewChild(MatSort) sort: MatSort;  
  constructor(private service: ClienteService) {
    this.service.getAllCliente().subscribe(data =>{  
      this.dataSource = new MatTableDataSource(data);  
      this.dataSource.paginator = this.paginator;  
      this.dataSource.sort = this.sort;  
    });
   }
  ngOnInit() {
    this.dataSource.paginator = this.paginator;  
    this.dataSource.sort = this.sort;  
  }
  applyFilter(filterValue: string) {  
    this.dataSource.filter = filterValue.trim().toLowerCase();  
  
    if (this.dataSource.paginator) {  
      this.dataSource.paginator.firstPage();  
    }  
  }  
}

Agora vamos definir a interface do usuário no arquivo cliente.component.html :

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Paginacao1</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" 
  integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" 
  crossorigin="anonymous">
</head>
<body>
  <app-root>Carregando...</app-root>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" 
  crossorigin="anonymous"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" 
  integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</body>
</html>

Agora no arquivo aluno.component.css inclua a definição do estilo:

th, td {
    text-align: left;
}

Agora é só alegria...

Na pasta do projeto , no prompt de comandos digite : ng serve -o

A seguir veremos no navegador o seguinte resultado:

Temos assim a paginação dos dados feita no Angular 7.

Pegue o projeto angular e Web API aqui :  ngalunos.zip  e  ApiAlunos_2.zip

"Quão amáveis são os teus tabernáculos, SENHOR dos Exércitos!
A minha alma está desejosa, e desfalece pelos átrios do Senhor; o meu coração e a minha carne clamam pelo Deus vivo."

Salmos 84:1-2

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti