o_template_do_nosso_componente - VWJavascript/Alurapic GitHub Wiki

O template do nosso componente

Agora precisamos definir o template de BotaoComponent:

<!-- alurapic/client/app/botao/botao.component.html -->

<button class="btn {{estilo}}" [type]="tipo" [disabled]="desabilitado">{{nome}}</button>

Vamos utilizá-lo no template de ListagemComponent:

<!--  alurapic/client/app/principal/components/principal.html -->

<painel *ngFor="let foto of fotos | filtroPorTitulo:textoProcurado.value" titulo="{{foto.titulo | uppercase}}" class="col-md-2">

    <a [routerLink]="['/cadastro', foto._id]">
        <foto titulo="{{foto.titulo}}" url="{{foto.url}}"></foto>
    </a>
    <br>
    <botao
        nome="Remover"
        estilo="btn-danger btn-block" 
        (click)="remove(foto)">
    </botao>
</painel>

Apenas os parâmetros nome e estilo foram passados, no entanto temos um problema. Quando clicamos em nosso botão, estamos executando o método remove de Principal e nenhum verificação é realizada. Para atingirmos nosso objetivo, o método remove só pode ser chamado após a confirmação do usuário. Você deve lembrar que criamos este novo componente para isolar a lógica de confirmação.

Primeiro, vamos remover a associação de evento click que acabamos de fazer:

// alurapic/client/app/listagem/listagem.component.html

<botao nome="Remover" estilo="btn-danger btn-block"></botao>

Vamos alterar o template do nosso botão adicionando uma ação para o evento click:

<!-- alurapic/client/app/botao/botao.component.html -->

<button (click)="executaAcao()" class="btn {{estilo}}" [type]="tipo" [disabled]="desabilitado">{{nome}}</button>

Precisamos adicionar esse método em BotaoComponent:

// alurapic/client/app/botao/botao.component.ts

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

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

    @Input() nome: string = 'Ok';
    @Input() estilo: string = 'btn-default';
    @Input() tipo: string = 'button';
    @Input() desabilitado: boolean = false;

    executaAcao() {

        if(confirm('Tem certeza?')) {
            // como executar o método `Remove` de principal?
        }
    }

}

Ótimo, quando nosso botão é clicado, ele executa a nossa confirmação, no entanto em nenhum momento indicamos que ele deve executar o método remove(foto) de ListagemComponent. Como seguir isso?

Eventos customizados com EventEmitter

A solução desse problema mora na criação de eventos customizados. Vamos fazer com que nosso botão dispare o evento acao, mas apenas quando houver confirmação. Como o evento sai do nosso componente para o mundo externo, vamos adicionar uma propriedade chamada acao na definição da nossa classe decorada com Output:

// alurapic/client/app/botao/botao.component.ts

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

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

    @Input() nome: string = 'Ok';
    @Input() estilo: string = 'btn-default';
    @Input() tipo: string = 'button';
    @Input() desabilitado: boolean = false;
    @Output() acao = new EventEmitter();

    executaAcao() {

        if(confirm('Tem certeza?')) {
            // como executar o método `Remove` de principal?
        }
    }

}

Veja que nosso evento acao recebe uma instância da classe EventEmitter. É através dessa instância que podemos indicarmos o disparo do evento.

Vamos disparar o evento através de acao.emit apenas quando o usuário confirmar a ação:

// alurapic/client/app/botao/botao.component.ts

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

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

    @Input() nome: string = 'Ok';
    @Input() estilo: string = 'btn-default';
    @Input() tipo: string = 'button';
    @Input() desabilitado: boolean = false;
    @Output() acao = new EventEmitter();

    executaAcao() {

        if(confirm('Tem certeza?')) {
            this.acao.emit(null); 
        }
    }
}

Mas como nosso botão saberá que deve executar remove de ListagemComponent? Para isso, precisamos associar o método remove com o evento acao do nosso botão no template de ListagemComponent:

// alurapic/client/app/listagem/listagem.component.html

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

<botao nome="Remover" estilo="btn-danger btn-block" (acao)="remove(foto)"></botao>

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

Perfeito! Quando clicamos em nosso botão, seu evento click será disparado e executará a lógica de confirmação. Se confirmarmos, através do EventEmitter dispararemos o evento acao. Isso fará com que a expressão remove(foto) atribuída ao evento acao seja executada.

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