Коммуникация между компонентами в Angular

В этом материале мы рассмотрим три метода передачи данных между компонентами в Angular и подумаем, какой подход лучше сработает в том или ином сценарии.

1: Передача данных через URL

Предположим, что мы переходим с одной страницы на другую (предыдущая страница уничтожается, и мы оказываемся на другой). Если данных для передачи не так много (например, только идентификатор объекта), для передачи данных можно использовать URL-адрес.

Существует два способа передачи данных через URL-адреса в Angular:

  • Параметры маршрутизатора
  • Параметры запросов

Если параметр является обязательным для компонента, тогда следует использовать параметр маршрутизатора. В противном случае можно использовать параметры запросов.

Параметры маршрутизатора

Параметры маршрутизатора являются обязательными. Такой параметр нужно зарегистрировать с URL-адресом в модуле маршрутизатора следующим образом:

const routes: Routes = [
  { path: 'list/:id', component: AppListComponent }
];

В этом примере list — это URL-адрес маршрута, а :id — параметр маршрутизатора, который является обязательным для передачи. AppListComponent — это компонент для подключения к этому маршруту.

Передача параметров маршрутизатора через директиву routerLink

<button
  type="button"
  [routerLink]="['/list', id]"
> 
  Show List
</button>

В этом примере id — это переменная, инициализированная в коде компонента, а /list — это маршрут, по которому мы хотим перемещаться.

Передача параметров маршрутизатора через сервис route 

id = 28;

constructor (private router: Router) {}

route() {
  this.router.navigate(['/list', this.id]);
}

Чтение параметров маршрутизатора

Параметр маршрутизатора можно прочитать из компонента, на который он направляется:

constructor(
  private activatedroute: ActivatedRoute
) {
  this.activatedroute.params.subscribe(data => {
    console.log(data);
  })
}

Параметры запросов

Параметры запросов являются необязательными. Регистрировать отдельный URL для этих параметров не нужно.

const routes: Routes = [
  { path: 'list', component: AppListComponent }
];

Здесь list — это URL-адрес маршрута, а AppListComponent — компонент.

Передача параметра запросов через директиву routerLink

<button
  type="button"
  [routerLink]="['/list']"
  [queryParams]="{id: '24'}"
> 
  Show List
</button>

В данном случае id — это ключ, а 24 —статическое значение. Также через переменную можно передать динамическое значение.

Передача параметра запросов через сервис route

id = 28;

constructor (private router: Router) {}

route() {
  this.router.navigate(['/list'], {queryParams: {id: this.id}});
}

Чтение параметров запросов

constructor(
  private activatedroute: ActivatedRoute
) {
  this.activatedroute.queryParams.subscribe(data => {
    console.log(data);
  })
}

Читайте также: Как использовать параметры запросов в Angular

2: Передача данных через @Input и @Output

Если вы хотите передать данные от дочернего компонента родительскому или наоборот, можно использовать @Input и @Output.

<app-child
  [jsonData]="data"
  (outputData)="data = $event"
></app-child>

Здесь data — это переменная, инициализированная в коде компонента.

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

@Component({
  selector: 'app-child',
  template: ''
})
export class AppChild implements OnInit {
  @Input()
  jsonData;
  @Output()
  outputData = new EventEmitter();
  constructor() {}

  ngOnInit() {
    console.log(this.jsonData);
  }

  emitData(data) {
    this.outputData(data);
  }
}

Таким образом можно передавать данные от дочернего компонента родительскому и обратно.

3: Передача данных через сервис и наблюдаемые объекты

Если у вас есть два одноуровневых компонента (или же они находятся на разных уровнях в иерархии), вы можете использовать сервис для передачи данных с помощью наблюдаемых объектов.

В этом примере мы используем субъект RxJS для создания наблюдаемого объекта:

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

@Injectable({providedIn: 'root'})
export class AppService {
  observer = new Subject();
  public subscriber$ = this.observer.asObservable();

  emitData(data) {
    this.observer.next(data);
  }
}

Читайте также: Субъекты поведения и воспроизведения RxJS

Чтобы передать данные, вы можете вызвать метод emitData этого сервиса, а для получения данных нужно подписаться на subsciber$, что делается следующим образом:

constructor(private appService: AppService) {}

ngOnInit() {
  this.appService.subscriber$.subscribe(data => {
    console.log(data);
  });
}

Итоги

На данный момент это все способы передачи данных между вашими компонентами, доступные в Angular.

Tags:

Добавить комментарий