Как реализовать передачу данных между двумя компонентами в Angular 7?

В Angular 7 существует несколько способов реализации передачи данных между компонентами. Одним из наиболее распространенных является использование сервисов и подписок на события.

Способ №1: Использование сервисов

1. Создайте сервис, в котором будет храниться общая информация или данные, которые нужно передать между компонентами. Например, назовем его DataService.

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

@Injectable({
  providedIn: 'root'
})
export class DataService {
  private data = new Subject<any>();

  setData(data: any) {
    this.data.next(data);
  }

  getData() {
    return this.data.asObservable();
  }
}

2. В компоненте, из которого нужно передать данные, внедрите сервис DataService в конструктор и используйте его метод setData(), чтобы отправить данные.

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-sender',
  template: `
    <button (click)="sendData()">Send Data</button>
  `
})
export class SenderComponent {
  constructor(private dataService: DataService) {}

  sendData() {
    const data = { text: 'Hello, World!' };
    this.dataService.setData(data);
  }
}

3. В компоненте, в который нужно передать данные, внедрите сервис DataService в конструктор и используйте его метод getData(), чтобы получить данные.

import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-receiver',
  template: `
    <p>{{ receivedData | json }}</p>
  `
})
export class ReceiverComponent implements OnInit {
  receivedData: any;

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.dataService.getData().subscribe(data => {
      this.receivedData = data;
    });
  }
}

Способ №2: Использование @Input и @Output декораторов

1. В компоненте, из которого нужно передать данные, создайте переменную с помощью декоратора @Output и определите метод, который будет передавать данные.

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

@Component({
  selector: 'app-sender',
  template: `
    <button (click)="sendData()">Send Data</button>
  `
})
export class SenderComponent {
  @Output() dataEvent = new EventEmitter<any>();

  sendData() {
    const data = { text: 'Hello, World!' };
    this.dataEvent.emit(data);
  }
}

2. В компоненте, в который нужно передать данные, используйте декоратор @Input для принятия данных и добавьте соответствующее событие в разметку.

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

@Component({
  selector: 'app-receiver',
  template: `
    <p>{{ receivedData | json }}</p>
  `
})
export class ReceiverComponent {
  @Input() receivedData: any;
}

3. В родительском компоненте, который объединяет оба компонента, добавьте обработчик события и передайте полученные данные в дочерний компонент.

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

@Component({
  selector: 'app-parent',
  template: `
    <app-sender (dataEvent)="receiveData($event)"></app-sender>
    <app-receiver [receivedData]="data"></app-receiver>
  `
})
export class ParentComponent {
  data: any;

  receiveData(data: any) {
    this.data = data;
  }
}

Оба способа имеют свои плюсы и минусы, и выбор зависит от ваших потребностей и решаемой задачи. С использованием сервисов вы можете передавать данные между компонентами, не имеющими прямой связи между собой, а с использованием @Input и @Output декораторов - между компонентами, имеющими прямую связь по иерархии.