Как обмениваться данными между компонентами с помощью сервиса в Angular 17

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

В Интернете есть несколько примеров, но у меня это не работает, я не знаю, что я сделал не так.

Кроме того, многие примеры основаны на старых версиях Angular, тогда как я хотел бы использовать для этого современные методы.

На данный момент у меня есть эти 3 файла, и я хочу поделиться значением «Тема»:

theme.service.ts:

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

@Injectable({
  providedIn: 'root'
})
export class ThemeService {
  private _theme: 'light'|'dark' = 'light';

  public get Theme() {
    return this._theme;
  }
  public set Theme(theme: 'light'|'dark') {
    this._theme = theme;
  }

  constructor() { }
}

приложение.компонент.ц:

import { Component, AfterViewInit } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { ThemeService } from './services/theme.service';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet],
  providers: [ThemeService],
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent implements AfterViewInit {

  constructor(private themeService: ThemeService) { }

  ngAfterViewInit() {
    console.info("app.component:", this.themeService.Theme);
    this.themeService.Theme = "dark";
    console.info("app.component:", this.themeService.Theme);
  }
}

мойкомпонент.компонент.ц:

import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { ThemeService } from '../../services/theme.service';

@Component({
  selector: 'app-mycomponent',
  standalone: true,
  imports: [],
  providers: [ThemeService],
  templateUrl: './mycomponent.component.html',
  styleUrl: './mycomponent.component.scss'
})
export class MyComponent implements AfterViewInit {

  constructor(private themeService: ThemeService) { }

  ngAfterViewInit() {
    console.info("mycomponent.component:", this.themeService.Theme);
  }
}

Я хотел бы получить такой результат:

app.component: light
app.component: dark
mycomponent.component: dark

Но у меня есть это:

app.component: light
app.component: dark
mycomponent.component: light

Я предполагаю, что два компонента используют разные экземпляры службы. Как мне сделать так, чтобы служба использовалась совместно между ними?

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
906
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не добавляйте ThemeService в массивы providers ваших компонентов. Сервис уже есть providedIn: 'root', а это значит, что у вас уже есть синглтон для приложения. Если вы добавите службу в массив providers для компонента, вы создадите вторую копию, о которой будет знать только этот компонент.

См. раздел Внедрение зависимостей и иерархия инжекторов руководства Начало работы с автономными компонентами (выделено мной):

Приложения Angular могут настроить внедрение зависимостей, указав набор доступных поставщиков. В типичном применении имеется два разных типа инжекторов:

  • модуль-инжектор с поставщиками, настроенными в @NgModule.providers или @Injectable({providedIn: "..."}). Эти поставщики всего приложения видны всем компонентам, а также другим службам, настроенным в инжекторе модулей.
  • узлы-инжекторы настроены в @Directive.providers/@Component.providers или @Component.viewProviders. Эти поставщики видны только данному компоненту и всем его дочерним элементам.

Другие вопросы по теме