0Pricing
Angular Academy · Урок

Хранилища сигналов в сервисах

Храните состояние приложения в сервисах на основе сигналов

«Хранилища сигналов в сервисах» — бесплатный урок Angular Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Angular Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Angular Academy содержит 4 уроков всего.

Сигналы как состояние

Сигналы Angular — это реактивные значения, которые уведомляют потребителей об изменениях. Сигнал хранит значение и повторно запускает любое вычисление или шаблон, который его читает.

Хранение сигналов внутри сервиса @Injectable позволяет нескольким компонентам использовать одно и то же реактивное состояние.

Минимальное хранилище сигналов

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

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

@Injectable({ providedIn: 'root' })
export class CounterStore {
  private _count = signal(0);
  readonly count = this._count.asReadonly();

  increment() { this._count.update(c => c + 1); }
}

Почему providedIn root

providedIn: 'root' делает сервис единственным экземпляром во всём приложении. Каждый компонент, который внедряет его, использует один и тот же экземпляр сигнала, поэтому состояние остаётся синхронизированным.

Чтение сигнала

Вызовите сигнал как функцию, чтобы прочитать его значение. В шаблоне Angular отслеживает такое чтение и автоматически обновляет DOM при изменении значения.

import { Component, inject } from '@angular/core';
import { CounterStore } from './counter.store';

@Component({
  selector: 'app-counter',
  template: '<button (click)="store.increment()">{{ store.count() }}</button>'
})
export class CounterComponent {
  store = inject(CounterStore);
}

asReadonly защищает состояние

asReadonly() возвращает сигнал, который можно читать, но нельзя изменять. Компоненты не смогут случайно вызвать для него set() или update(), поэтому все изменения проходят через методы хранилища.

set и update

Используйте set(value), когда следующее значение уже известно. Используйте update(fn), когда следующее значение зависит от текущего.

private _user = signal<User | null>(null);

setUser(u: User) { this._user.set(u); }
clearUser() { this._user.set(null); }
touch() { this._user.update(u => u ? { ...u, seen: true } : u); }

Несколько сигналов в одном хранилище

Хранилище может содержать несколько сигналов, представляющих разные части состояния. Оставляйте каждый изменяемый сигнал приватным и открывайте соответствующие представления только для чтения.

private _items = signal<Item[]>([]);
private _loading = signal(false);

readonly items = this._items.asReadonly();
readonly loading = this._loading.asReadonly();

Методы инкапсулируют логику

Бизнес-правила должны находиться в методах хранилища, а не в компонентах. Компоненты вызывают методы, явно выражающие намерение, например addToCart(item), а хранилище решает, как изменить состояние.

addToCart(item: Item) {
  this._items.update(list => [...list, item]);
}
removeFromCart(id: string) {
  this._items.update(list => list.filter(i => i.id !== id));
}

Подписки не нужны

В отличие от сервисов на основе RxJS, хранилищам сигналов не нужны subscribe() и ручная отмена подписок. Чтение сигнала в шаблоне настраивает реактивность, а Angular очищает её при уничтожении компонента.

Внедрение с помощью inject()

Функция inject() работает в конструкторах, инициализаторах полей и фабричных функциях. Это современный способ получить экземпляр хранилища.

export class CartComponent {
  private store = inject(CartStore);
  items = this.store.items; // read-only signal
}

Тестирование хранилища сигналов

Хранилища сигналов — это обычные классы, поэтому тесты просты: создайте экземпляр, вызовите метод и синхронно прочитайте значение сигнала. Дополнительная асинхронная инфраструктура не требуется.

it('increments', () => {
  const store = new CounterStore();
  store.increment();
  expect(store.count()).toBe(1);
});

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете хранилища сигналов.

Итоги

Вы научились создавать хранилище на основе сигналов: оставлять изменяемые сигналы приватными, открывать представления asReadonly(), изменять состояние через set/update внутри методов и внедрять единственный экземпляр с помощью inject(). Подписки не нужны, тестирование просто, реактивное состояние общее.

Часто задаваемые вопросы

Урок «Хранилища сигналов в сервисах» бесплатный?

Да — полный текст урока «Хранилища сигналов в сервисах» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Angular Academy, подпишись на CoddyKit PRO. Курс Angular Academy содержит 4 уроков всего.

Чему я научусь в уроке «Хранилища сигналов в сервисах»?

Храните состояние приложения в сервисах на основе сигналов Ты практикуешь Angular Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Angular Academy?

Предыдущий опыт не требуется. Angular Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Хранилища сигналов в сервисах»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Angular Academy?

Да. Каждый урок Angular Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Хранилища сигналов в сервисах
  2. Выведение состояния с помощью computed
  3. Иммутабельное обновление состояния
  4. Связывание сигналов и RxJS
← Назад к Angular Academy