Neste artigo, veremos como podemos passar dados entre componentes irmãos na máquina cliente. 

No Angular, dividimos nossa página da web em vários componentes e a relação entre esses componentes forma uma estrutura em forma de árvore. Um componente pode ter um pai e vários filhos. Dito isso, também pode ter irmãos. Em algumas situações, precisamos passar dados entre esses componentes independentes. Passar os dados é fácil e torna nosso código mais limpo e mais legível enquanto trabalhamos em um grande projeto.

Pré-requisitos: o NPM deve ser pré-instalado.

Para entender como funciona, veja o diagrama abaixo:

  • No caso de um evento de usuário, podemos emitir dados de um componente.
  • Esses dados serão enviados ao componente pai.
  • O componente pai pode transferir posteriormente esses dados na forma de uma entrada para o outro componente filho.
  • É uma transmissão de mão única, mas podemos usá-la de outra forma para fazer um canal de comunicação bidirecional.

No Angular, podemos conseguir isso usando seus recursos embutidos:

  • O decorador @Output ajuda a emitir os dados por meio de um objeto EventEmitter <T>. Veremos seu funcionamento por meio do exemplo.
  • O componente pai irá capturar os dados como uma variável $event. Ele pode usá-lo em um método ou transmiti-lo por outros meios.
  • Finalmente, o decorador @Input() usa uma variável e qualquer entrada por meio do pai será armazenada nesta variável.

Vamos ver tudo isso por meio de um exemplo simples. Nesta postagem, veremos uma página da web simples que pega palavras-chave como entrada do usuário em um componente e exibe as linhas correspondentes em outro componente.

Vamos configurar o ambiente primeiro:

  • Instale cli angular. Execute como administrador ou use sudo em caso de erros de permissão.
npm i -g @angular/cli
  • Quando o angular CLI é instalado, inicie um novo projeto usando o seguinte comando:
ng new <project-name>
  • Agora teste usando:
ng serve -o
  • Se a página inicial angular puder ser acessada em http: // localhost: 4200, a configuração foi bem-sucedida. Limpe o conteúdo de app.component.html antes de prosseguir.
  • Depois disso, gere dois novos componentes:
ng generate component search
ng generate component table
  • Você verá dois diretórios 'search' e 'table' na pasta do aplicativo. Ambos terão 4 novos arquivos cada.

Vamos fazer nosso componente de busca e emitir um evento a partir dele. Primeiro, em search.component.html, escreva o seguinte código:

<br><br>
<div>
    <label for="search">Enter the text</label>
    <br>
    <br>
    <input type="text" id="search" placeholder="type some words" 
           (keyup)="emit(keyword.value);" #keyword>
</div>

No código acima, há um campo de entrada simples que usa uma função emit() quando ocorre um evento keyup. Usaremos isso para emitir a palavra-chave para o componente pai. Vamos definir este método e evento em search.component.ts :

import { Component, EventEmitter, OnInit, Output } 
        from '@angular/core';
  
@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
  
  constructor() { }
  ngOnInit(): void {
  }
  @Output() emitter:EventEmitter<string>
       = new EventEmitter<string>();
  
  emit(keyword){
      this.emitter.emit(keyword);
  }
}

O objeto emissor do tipo “string” emitirá o parâmetro especificado em seu método emit(). No evento keyup, o método emit() executa o método emit() do objeto emissor.

Agora vamos preencher o código em table.component.ts :

import { Component, DoCheck, Input, OnInit } from '@angular/core';
  
@Component({
  selector: 'app-table',
  templateUrl: './table.component.html',
  styleUrls: ['./table.component.css']
})
export class TableComponent implements OnInit, DoCheck {
  data = [
    {name:"Liam", age:"20", post: "Marketing Coordinator"},
    {name:"Noah", age:"25" , post:"Medical Assistant"},
    {name:"Oliver", age:"22", post:"Web Designer"},
    {name:"William", age:"20", post:"Dog Trainer"},
    {name:"Bill", age: "22", post:"President of Sales"},
    {name:"James", age: "19", post:"Project Manager"},
  ];
  items = [];
  constructor() { }
  @Input() keyword:string;
  
  ngOnInit(): void {
    this.refresh();
  }
  
  ngDoCheck(){
    this.refresh();
  }
  
  refresh(){
    this.items = [];
    this.data.forEach(
      item => {
        if(item.name.search(this.keyword) != -1
         || item.age.search(this.keyword) != -1 
         || item.post.search(this.keyword) != -1) {
          this.items.push(item)
        }
      }
    ) 
  }
}

Declaramos um objeto de dados que são alguns dados estáticos para nossa tabela neste exemplo. 

  • A variável “palavra-chave” é definida como entrada para este componente usando o decorador @Input().
  • Declaramos um método refresh() que preenche a lista de itens usando se o conteúdo for correspondido em qualquer um dos campos com a variável “palavra-chave”.
  • Chamamos esse método nos métodos ngDoCheck e ngOnInit (observe que temos que implementar a interface para eles). O método ngDoCheck é chamado de detecção pós-alteração no aplicativo. Portanto, sempre que a palavra-chave muda em pai, este método substituirá a lista.
  • Mostraremos essa lista na table.component.html usando o código a seguir:
<p *ngIf="!items.length">No results found</p>
  
<table class="table" *ngIf="items.length">
    <thead >
        <td>Name</td>
        <td>Age</td>
        <td>Post</td>
    </thead>
    <br>
    <tr *ngFor="let item of items">
        <td>{{item.name}}</td>
        <td>{{item.age}}</td>
        <td>{{item.post}}</td>
    </tr>
</table>

O código acima exibe a tabela presente no array “itens”. Agora vamos escrever o código para o componente pai app.component.ts :

import { Component } from '@angular/core';
  
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'GeeksForGeeks';
  keyword = "";
  send(keyword){
    this.keyword = keyword;
  }
}

No código acima:

  • Declaramos uma variável de palavra-chave.
  • O método send() pega a palavra-chave como parâmetro e a define como a variável de classe.
  • Usaremos a variável de classe “palavra-chave” como entrada para o componente da tabela.
  • O evento emitido pelo componente de pesquisa será tratado pelo método send().
  • Veja o código abaixo para app.component.html :
<div>
  <app-search (emitter)="send($event)"></app-search>
</div>
<hr>
  
<div>
  <app-table [keyword]="keyword"></app-table>
</div>

Neste código:

  • A variável “$event” representa os dados emitidos pelo componente de pesquisa.
  • A variável de palavra-chave do componente da tabela é passada como [palavra-chave].

Agora salve todos os arquivos e teste o código usando:

ng serve -o

Em http: // localhost: 4200 podemos ver o resultado.

Saída: