Ваше необходимое решение доступно в этом учебном пособии , написанном Джеффом Делани .
Несвязанные компоненты: обмен данными со службой
При передаче данных между компонентами, не имеющими прямого соединения, такими как братья и сестры, внуки и т. Д., Вам следует использовать общую службу.Когда у вас есть данные, которые должны были быть синхронизированы, RxJS BehaviorSubject очень полезен в этой ситуации.
Вы также можете использовать обычный RxJS Subject для обмена данными через службу, но вот почему я предпочитаю BehaviorSubject.
- Всегда будет возвращать текущее значение при подписке - нет необходимости вызывать onnext
- . Имеет функцию getValue () для извлечения последнего значения в виде необработанных данных.
- Это гарантирует, что компонент всегда получает самые последние данные
В сервисе мы создаем частный объект BehaviorSubject, который будет содержать текущее значение сообщения.Мы определяем переменную currentMessage, обрабатывающую этот поток данных как наблюдаемую, которая будет использоваться компонентами.Наконец, мы создаем функцию, которая вызывает следующий объект BehaviorSubject для изменения его значения.
Все родительские, дочерние и родственные компоненты получают одинаковую обработку.Мы внедряем DataService в конструктор, затем подписываемся на наблюдаемую currentMessage и устанавливаем ее значение равным переменной сообщения.
Теперь, если мы создадим функцию в любом из этих компонентов, которая изменяет значение сообщения.при выполнении этой функции новые данные автоматически передаются всем другим компонентам.
data.service.ts:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable()
export class DataService {
private messageSource = new BehaviorSubject('default message');
currentMessage = this.messageSource.asObservable();
constructor() { }
changeMessage(message: string) {
this.messageSource.next(message)
}
}
parent.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-parent',
template: `
{{message}}
`,
styleUrls: ['./sibling.component.css']
})
export class ParentComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
}
sibling.component.ts:
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-sibling',
template: `
{{message}}
<button (click)="newMessage()">New Message</button>
`,
styleUrls: ['./sibling.component.css']
})
export class SiblingComponent implements OnInit {
message:string;
constructor(private data: DataService) { }
ngOnInit() {
this.data.currentMessage.subscribe(message => this.message = message)
}
newMessage() {
this.data.changeMessage("Hello from Sibling")
}
}