Паттерн "Медиатор"
Рассмотрим пример, где у нас есть три компонента: ComponentA
, ComponentB
, и ComponentC
, которые взаимодействуют друг с другом через посредника.
Для начала создадим сервис, который будет выступать в роли посредника:
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class MediatorService { private events = new Subject<any>(); public events$ = this.events.asObservable(); emit(event: string, payload: any) { this.events.next({ event, payload }); } }
Далее приступим к созданию всех компонентов. Начнем с ComponentA
, он будет отправлять событие через посредника:
import { Component } from '@angular/core'; import { MediatorService } from './mediator.service'; @Component({ selector: 'app-component-a', template: `<button (click)="sendMessage()">Send Message from A</button>` }) export class ComponentA { constructor(private mediatorService: MediatorService) {} sendMessage() { this.mediatorService.emit('messageFromA', 'Hello from Component A'); } }
Компонент ComponentB
будет подписываться на события и отправлять свои:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { MediatorService } from './mediator.service'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-component-b', template: ` <div *ngIf="message">{{ message }}</div> <button (click)="sendMessage()">Send Message from B</button> ` }) export class ComponentB implements OnInit, OnDestroy { private subscription: Subscription; message: string; constructor(private mediatorService: MediatorService) {} ngOnInit() { this.subscription = this.mediatorService.events$.subscribe(({ event, payload }) => { if (event === 'messageFromA') { this.message = payload; } }); } ngOnDestroy() { this.subscription.unsubscribe(); } sendMessage() { this.mediatorService.emit('messageFromB', 'Hello from Component B'); } }
Компонент ComponentC
будет подписываться на события:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { MediatorService } from './mediator.service'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-component-c', template: `<div *ngIf="message">{{ message }}</div>` }) export class ComponentC implements OnInit, OnDestroy { private subscription: Subscription; message: string; constructor(private mediatorService: MediatorService) {} ngOnInit() { this.subscription = this.mediatorService.events$.subscribe(({ event, payload }) => { if (event === 'messageFromB') { this.message = payload; } }); } ngOnDestroy() { this.subscription.unsubscribe(); } }
Далее все компоненты объединим в модуль:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { ComponentA } from './component-a'; import { ComponentB } from './component-b'; import { ComponentC } from './component-c'; @NgModule({ declarations: [ AppComponent, ComponentA, ComponentB, ComponentC ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
<app-component-a></app-component-a> <app-component-b></app-component-b> <app-component-c></app-component-c>
В этом примере ComponentA
отправляет сообщение через MediatorService
, ComponentB
получает это сообщение и отображает его, а также может отправить своё сообщение, которое затем получает ComponentC
. Таким образом, все компоненты взаимодействуют через посредника, минимизируя прямую связанность между ними.