Это возможно и является нормальным способом, которым сервисы ведут себя в Angular.Сервисы создаются как одиночные в зависимости от того, где вы provide
их.Предоставление службы на корневом уровне гарантирует, что все компоненты, внедряющие эту службу, получат одну и ту же ссылку, а не новый экземпляр.Это делается путем передачи метаданных в декоратор @Injectable
.
Давайте создадим сервис, предоставим его на корневом уровне и внедрим в два компонента.Каждый компонент получит одну и ту же ссылку.Если мы добавляем наблюдаемую к службе, и оба компонента подписываются на нее, они получают одинаковые значения.Когда это значение изменится, оно будет обновлено в обоих компонентах.
Служба:
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class MyService {
public message$: Observable<string>;
private message: BehaviorSubject<string>;
constructor() {
this.message = new BehaviorSubject('default message');
this.message$ = this.message.asObservable();
}
public updateMessage(message: string): void {
this.message.next(message);
}
}
Компоненты (они почти в точности совпадают друг с другом):
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'my-first-component',
template: `
<p>first component: {{ message$ | async }}</p>
`
})
export class MyFirstComponent implements OnInit {
public message$: Observable<string>;
constructor(private myService: MyService) {}
ngOnInit() {
this.message$ = this.myService.message$;
this.myService.updateMessage('new message')
}
}
@Component({
selector: 'my-second-component',
template: `
<p>second component: {{ message$ | async }}</p>
`
})
export class MySecondComponent implements OnInit {
public message$: Observable<string>;
constructor(private myService: MyService) {}
ngOnInit() {
this.message$ = this.myService.message$;
}
}
Если вы посмотрите на шаблоны двух компонентов, мы подписываемся на наблюдаемое в сервисе и отображаем сообщение.По умолчанию для сообщений установлено значение 'default message'
, установленное службой.
Обратите внимание, что в ngOnInit
в первом компоненте мы обновляем сообщение в этой строке: this.myService.updateMessage('new message')
.Обратите внимание, что это только в первом компоненте, но не во втором компоненте.Если вы запустите это в приложении, сообщение будет обновлено на обоих компонентах до 'new message'
.Это показывает, что это тот же экземпляр MyService
и может использоваться и обновляться любым количеством компонентов.