Entendendo @Input, @Output e EventEmitter em Angular

Para aqueles que são novos na Angular, os decoradores de Input e Output estão um pouco confusos, especialmente quando você está estudando eles, olhando para o código de exemplo. Neste artigo, vou tentar explicá-los da forma mais simples.

Uma ferramenta para trocar dados

Primeiro de tudo, a ideia de Input e Output é trocar dados entre componentes. Eles são um mecanismo para enviar/receber dados de um componente para outro.

Input é usado para receber os dados de entrada enquanto que Output é usado para enviar os dados de saída. A Saída envia dados pelos produtores de eventos, geralmente objetos EventEmitter.

Então quando você vê um código como este

@Component({
selector: 'todo-item',
...
})export class TodoItemComponent {
@Input() item
@Output() onChange = new EventEmitter()
}

isso significa

  • hey, eu estou esperando dados sendo enviados para mim. Eu vou recebê-los e armazená-los na minha propriedade do item
  • por sinal, eu vou produzir e enviar dados através da propriedade onChange.

Vamos dizer que você tem um componente TodoList que contém o componente TodoItem. No modelo TodoList, espera-se que você veja

...
<todo-item
="myTask"
(onChange)="handleChange($event)"
</todo-item>
...

o que significa

  • TodoList coloca valores de dados em sua propriedade myTask e os passa para TodoItem
  • dados emitidos de TodoItem serão recebidos e manipulados pela função handleChange() em TodoList

É isso para a teoria. Vamos dar uma olhada no exemplo.

@Input e @Output em ação

Check out this example. Aqui eu criei 2 componentes, olá componente aninhado dentro do componente app. O componente hello tem um Input e um Output

hello.component.ts
@Component({
selector: 'hello',
template: `
<h3 (click)="onClick.emit('Neo')">
...
</h3>
`
})export class HelloComponent {
@Input() myFriend: string
@Output() onClick = new EventEmitter()
}

Ele espera receber um valor de string e armazena-o na propriedade myFriend.

@Input() myFriend: string

A cada vez que você clicar nele, a propriedade Output noClick irá emitir uma string ‘Neo’ para o mundo exterior.

<h3 (click)="onClick.emit('Neo')">

Below é o componente app

app.component.ts
export class AppComponent {
ng = 'Angular'
myName = 'Neo' upCase(st:string): void { ... }
}app.component.html
<hello myFriend="{{ ng }}" (onClick)="upCase($event)"></hello>
<h3>My name is {{ myName }}</h3>

Note que o componente app usa a tag hello no seu template e faz duas coisas:

  • passando um valor de string ‘Angular’ para hello através da sua propriedade ng
<hello myFriend="{{ ng }}"
  • recebendo o valor emitido pelo hello e processando esse valor pela função upCase()
<hello myFriend="{{ ng }}" (onClick)="upCase($event)">

Você pode ver a aplicação em ação aqui