2
respostas

[Dúvida] @Input() @Output()

Boa tarde, alguém tem algum exemplo sobre @Input e @Output pra eu entender melhor ! Tenho uma classe que no banco de dados ela possui 14 mil tabelas para ser carregadas em um formulário select, e eu gostaria de fazer melhor usando esse metodo do angular !!!

2 respostas

Olá Ighor, tudo bom?

Vamos lá.

O @Input() e @Output() são recursos que permitem a comunicação entre componente, e essa comunicação só pode ser feita de componente filho para componente pai e vice versa.

Sendo que o @Input() permite a comunicação usando o property binding. Imagina o seguinte, tenho um componente Pai que possui um array de convidados,

Classe do AppComponent

export class AppComponent {
  title = 'novo-projeto';

  listaDeConvidados = [
    `Carson Jenkins`,
    `Nathaly Floyd`,
    `Roderick Curry`,
  ]
}

e tenho um componente filho de um card para exibir a informação de cada convidado. Para que eu consiga renderizar o nome de cada um dos convidados, eu preciso criar uma propriedade de entrada com o decorator @Input() Classe do ConvidadoComponent

export class ConvidadoComponent implements OnInit {
  @Input() convidado = '';
  constructor() { }

  ngOnInit(): void {
  }
}

e realizar uma property binding.

Template do AppComponent

<header>
  Lista de Convidados - Festa Fantasia
</header>

<div *ngFor="let c of listaDeConvidados">
  <app-convidado [convidado]="c"></app-convidado>
</div>

Para que o ConvidadoComponent receba somente o nome de cada convidado da lista eu fiz um *ngFor que vai percorrer a lista e atribuir cada convidado na variavel c e depois eu atribuo c na propriedade de entrada do ConvidadoComponent.

E esse será o resultado:

Print da aplicação com três card com uma imagem ilustrativa de perfil com um nome ficticio em cada um dos cards.

Para exibir o nome, realizar uma interpolação, passando o nome da propriedade no template.

Template ConvidadoComponent

<div class="card">
  <img src="https://img.freepik.com/vetores-premium/icone-de-perfil-de-avatar_188544-4755.jpg?w=2000" width="150" height="150" alt="">

  <p>{{convidado}}</p>
</div>

Já o @Output() funciona como emissor de eventos para envio de uma informação para o componente pai, onde essa informação será passada como parâmetro por uma função.

Sendo assim para utilizar é necessário dizer que a propriedade de saida receberá um new EventEmitter().

Voltando para o exemplo da lista de convidados, imagine que eu precise de uma funcionalidade para excluir alguns convidados, no meu ConvidadoComponent irem criar a propriedade de saida e o método de excluir onde vou emitir o valor de convidado.

export class ConvidadoComponent implements OnInit {
  @Input() convidado = '';
  @Output() emitirConvidado = new EventEmitter();
  constructor() { }
  excluirConvidado() {
    this.emitirConvidado.emit(this.convidado);
  }
}

E no template deste coomponent vou criar o botão de excluir.

<div class="card">
  <img src="https://img.freepik.com/vetores-premium/icone-de-perfil-de-avatar_188544-4755.jpg?w=2000" width="150" height="150" alt="">

  <p>{{convidado}}</p>
  <button (click)="excluirConvidado()">X</button>
</div>

Agora, para que o componente saiba o que está acontecendo, é necessário vincular o evento emissor com uma função do AppComponent. Template do AppComponent


<header>
  Lista de Convidados - Festa Fantasia
</header>

<div *ngFor="let c of listaDeConvidados">
  <app-convidado [convidado]="c" (emitirConvidado)="excluirConvidado($event)"></app-convidado>
</div>

Classe do AppComponent

export class AppComponent {
  title = 'novo-projeto';

  listaDeConvidados = [
    `Carson Jenkins`,
    `Nathaly Floyd`,
    `Roderick Curry`,
  ]

  excluirConvidado(convidado: string){
    console.log(convidado);
  }
}

Agora basta eu criar a lógica para excluir o item que corresponde ao nome que a propriedade convidado carrrega. Método de excluir do AppComponent

excluirConvidado(convidado: string){
    const index = this.listaDeConvidados.indexOf(convidado)
    this.listaDeConvidados.splice(index, 1)
}

Espero que tenha esclarecido sua dúvida.

Vou subir o projeto no repósitorio GitHub para que possa análisar melhor.

Abraço.