DEV Community

Renan C. Ferro
Renan C. Ferro

Posted on • Updated on

@Output(), compartilhando dados entre filho e pai, e até avô !

Alt Text

Imagine o cenário acima, que na qual por algum motivo precisamos avisar o componente modal(Pai) que houve um click no botão(Filho), para que assim o componente pai através de um método que só ele tem contabilize o total de clicks em seu componente filho.

Então, se formos pensar em algumas possibilidades para utilizar o método que contabiliza o total de click poderíamos talvez criar uma service e remover o método do componente pai, e se você for bem "malaco" talvez possa pensar na idéia de importar o componente-pai.component.ts dentro do componente-filho.componente.ts, o que como meu líder Vitor Hugo, o "Vitão" disse, é extremamente e simplesmente proibido importar componente.ts ! haha

Então, voilà, temos a maravilhosa propriedade @Output()

Propriedade @Output()

Quando utilizamos o @Output() marcamos uma propriedade que permite o fluxo de dados do componente filho para o componente pai. Essa propriedade gera um evento que notifica para o componente pai que algo aconteceu no componente filho, e para emitirmos esse evento para o componente pai, utilizamos o EventEmiter do @angular/core.

How to do ...

Primeiro, precisamos importar o Output e nosso EventEmitter na classe do nosso componente:

import { Output, EventEmitter } from '@angular/core';
Enter fullscreen mode Exit fullscreen mode

Depois, precisamos declarar nossa @Output(), que será como "a nossa fala" para nosso componente pai:

@Output() houveUmClick = new EventEmitter<void>();

constructor() {}
Enter fullscreen mode Exit fullscreen mode

Nosso new EventEmitter, diz que o angular tem que criar um emissor de eventos do tipo void, mas, podemos passar string, objetos e tudo mais. Porém, em nosso exemplo precisamos só emitir que ocorreu um click, então podemos passar como void !

Depois de criado, precisamos pensar quando queremos informar para nosso componente pai que houve um click, como por exemplo no cenário abaixo:

  • Quando um método retornar sucesso ou simplesmente quando for iniciado, então, declaramos:
ngOnInit(): void {

   this.houveUmClick.emit();
}
Enter fullscreen mode Exit fullscreen mode

Na linha de código, queremos dizer o seguinte:

  • Angular, quando você iniciar o componente, fala para o componente pai que se estiver me ouvindo que houve um click e que ele resolve o que fazer, e fazemos isso através do .emit();

Caso o nosso componente pai esteja esperando alguma string ou alguma outra coisa, teríamos que ter criado um EventEmitter(); e quando fossemos emitir que houve uma ação, em nosso emit() passaríamos o que nosso componente pai esta esperando. No caso do exemplo, só precisamos alertar que houve um evento com o componente filho então podemos passar vazio.

E após isso, esta feito, nosso componente filho ja esta falando houve um evento com ele, agora nosso componente pai precisa passar a nos ouvir.

Como ouvir nosso componente filho ...

Após termos criado nossa @Output() em nosso componente filho o componente pai precisa passar a ouvir-lo, então fazemos isso da seguinte forma:

Quando declaramos nosso componente filho em nosso html, precisamos passar nele também o @Output() que criamos nele, que é a forma como ele irá falar com o componente pai, da seguinte forma:

<div class="main-content">
   <app-component-button (houveUmClick)="adicionaMaisUmCickContabilizado()"></app-component-button>
</div>
Enter fullscreen mode Exit fullscreen mode

Então, o houveUmClick é o nome da "forma" que nosso filho irá falar com a gente, e após ele falar, eu pego e chamo o método do componente pai que é adicionaMaisUmCickContabilizado() e nele eu faço o que é preciso.

Vale lembrar que podemos passar mais de um emissor e para mais de um componente filho. Agora, uma pergunta super válida:

  • E se eu precisar que o componente "vô" do meu componente pai saiba que houve um click? Se eu precisasse subir um nível ainda na hierarquia ?

A resposta é simples, assim como criamos uma @Output() em nosso filho para que ele consiga falar, teríamos que criar uma @Output() em nosso componente pai, para que assim ele consiga conversar com o componente pai dele e o componente "vô" passaria a escuta-lo e fazer o que precisa ser feito :D

Obrigado pela leitura e até a próxima ! :D :D

Discussion (0)