Паттерн "Медиатор"
Рассмотрим пример, где у нас есть три компонента: 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. Таким образом, все компоненты взаимодействуют через посредника, минимизируя прямую связанность между ними.