implementando_o_filtro - VWJavascript/Alurapic GitHub Wiki

Implementando o filtro

Agora que temos tudo encaixado, podemos concluir a lógica do nosso filtro:

// alurapic/client/app/foto/foto.pipes.ts

import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
    name: 'filtroPorTitulo'
})
export class FiltroPorTitulo implements PipeTransform {

    transform(fotos, digitado) {

        digitado = digitado.toLowerCase();
        return fotos.filter( foto => foto.titulo.toLowerCase().includes(digitado));
    }
}

Para ficar moderno, estou usando uma arrow function, yeah! Vamos dissecar esse código. Primeiramente, o método transform será chamado toda vez que digitarmos no campo do filtro. Daí, capturamos o que o usuário digitou na variável filtro. Se temos a lista de fotos e o filtro, podemos filtrar a lista retornando apenas as fotos que tenham como título parte do que digitamos. Se filtro possui valor (usuário digitou algo), filtramos a lista pelo valor do filtro, mas se filtro estiver em branco (quando não há valor algum), retornamos a lista de fotos com todos os seus elementos. Escrevemos um código que faz muita coisa com pouquíssimas linhas!

Porém, durante a escrita do nosso código não tivemos o recurso do autocomplete, porque não tipamos o parâmetro do método transform. Vamos fazer isso agora e reescrever a função com auxílio do editor?

// alurapic/client/app/foto/foto.pipes.ts

import { Pipe, PipeTransform } from '@angular/core';
import { FotoComponent } from './foto.component';
@Pipe({
    name: 'filtroPorTitulo'
})
export class FiltroPorTitulo implements PipeTransform {

    transform(fotos: FotoComponent[], digitado: string) {

        digitado = digitado.toLowerCase();
        return fotos.filter( foto => foto.titulo.toLowerCase().includes(digitado));
    }
}

O primeiro parâmetro agora é um array de FotoComponent e o segundo uma string. Como o primeiro tipo foi criado por nós, precisamos importar sua classe. Como o nosso compilador TypeScript conhece os tipos, pudemos realizar o autocomplete. Porém, o mesmo não foi possível para foto.titulo. Como não tipamos os atributos da classe Foto, o TypeScript não poderá ajudar nosso editor. Que tal realizarmos a tipagem agora?

Inclusive, vamos aproveitar e criar a propriedade descricao que usaremos no próximo capítulo. Contudo, esta propriedade não usará o decorator Input, pois só queremos que o componente receba apenas a URL e o título como parâmetros:

// alurapic/client/app/foto/foto.component.ts

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

@Component({
    moduleId: module.id,
    selector: 'foto',
    templateUrl: './foto.component.html' 
})
export class FotoComponent {

    @Input() titulo: string;
    @Input() url: string;
    descricao: string;
}

Elaboramos todo nosso código, mas quando digitamos no campo de filtro a lista de fotos não é filtrada. O que está acontecendo? Os dados estão chegando no filtro e ele parece estar funcionando perfeitamente. Certamente é um problema na atualização da view.

Isso acontece porque Angular só atualizará a view em resposta a um evento assíncrono. Veja, evento! Quando digitamos no campo, não estamos disparando evento algum. Que tal se dispararmos um evento de mentirinha, que nada faz mas que sinalizará para o Angular atualizar a view?

Realizando o truque:

<!-- alurapic/client/app/listagem/listagem.component.html -->
<!-- código anterior omitido -->

 <input class="form-control" #textoProcurado (keyup)="0"  
            placeholder="filtrar pelo título da foto">

<!-- código posterior omitido -->

Veja que estamos envolvendo o atributo keyup entre parênteses, a sintaxe do Angular 2 para associação de eventos, ou no inglês event binding. Toda vez que digitarmos no campo, o evento keyup que nada faz será disparado e mesmo não executando lógica nenhuma, fará com que o Angular atualize nossa view e por conseguinte a nossa lista filtrada.

⚠️ **GitHub.com Fallback** ⚠️