Comunicação entre Componentes no Angular: Decoradores @Input, @Output, @ViewChild e Serviços

Criação de Componentes no Angular

Para gerar um novo componente no Angular, utilize o comando CLI. Exemplo para criar um componente chamado "perfil" no diretório "componentes":

ng g component componentes/perfil

Isso criará arquivos padrão como template HTML, estilos e classe TypeScript, e atualizará o módulo automaticamente.

Criação e Uso de Serviços

Serviços no Angular são classes injetáveis para lógica de negócios compatrilhada. Crie um serviço com:

ng g service servicos/dados-usuario

O serviço gerado usa o decorador @Injectable para permitir injeção de dependência. Exemplo de implementação:

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class DadosUsuarioService {
  private usuarioAtual = 'João Silva';

  obterNomeUsuario(): string {
    return this.usuarioAtual;
  }
}

Para usar o serviço, injete-o em um componente:

import { Component } from '@angular/core';
import { DadosUsuarioService } from '../servicos/dados-usuario.service';

@Component({
  selector: 'app-painel',
  template: '<p>{{ nome }}</p>'
})
export class PainelComponent {
  nome: string;

  constructor(private dadosService: DadosUsuarioService) {
    this.nome = this.dadosService.obterNomeUsuario();
  }
}

Passagem de Dados do Pai para o Filho com @Input

Use o decorador @Input para receber dados do componente pai. No componente filho, declare uma propriedade de entrada:

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

@Component({
  selector: 'app-filho',
  template: '<p>Mensagem: {{ mensagem }}</p>'
})
export class FilhoComponent {
  @Input() mensagem: string;
}

No template do componente pai, passe os dados usando binding de propriedade:

<app-filho [mensagem]="textoDoPai"></app-filho>

No componente pai, defina a propriedade:

export class PaiComponent {
  textoDoPai = 'Olá do componente pai!';
}

Acesso ao Componente Filho com @ViewChild

Para acessar diretamente um componente filho ou elemento DOM, use @ViewChild. No componente pai, referencie o filho com uma variável de template:

<app-filho #refFilho></app-filho>
<button (click)="lerDadosFilho()">Ler Dados do Filho</button>

No componente pai, obtenha a referência:

import { Component, ViewChild } from '@angular/core';
import { FilhoComponent } from './filho.component';

@Component({
  selector: 'app-pai',
  templateUrl: './pai.component.html'
})
export class PaiComponent {
  @ViewChild('refFilho') componenteFilho: FilhoComponent;

  lerDadosFilho() {
    const dado = this.componenteFilho.dadoSecreto;
    console.log('Dado do filho:', dado);
  }
}

No componente filho, exponha uma propriedade pública:

export class FilhoComponent {
  dadoSecreto = 'Informação interna do filho';
}

Passagem de Dados do Filho para o Pai com @Output

Use @Output com EventEmitter para enviar dados ao pai. No componente filho:

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

@Component({
  selector: 'app-filho',
  template: '<button (click)="enviarEvento()">Notificar Pai</button>'
})
export class FilhoComponent {
  @Output() notificacao = new EventEmitter<string>();

  enviarEvento() {
    this.notificacao.emit('Filho clicou!');
  }
}

No template do componente pai, escute o evento:

<app-filho (notificacao)="aoReceberNotificacao($event)"></app-filho>
<p>{{ resultado }}</p>

No componente pai, trate o evento:

export class PaiComponent {
  resultado: string;

  aoReceberNotificacao(mensagem: string) {
    this.resultado = mensagem;
  }
}

Tags: Angular TypeScript @Input @Output @ViewChild

Publicado em 6-20 20:32