Signal Stores en servicios
Mantener el estado de la aplicación en servicios basados en signals
Signal Stores en servicios es una lección gratuita de Angular Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Angular Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Angular Academy incluye 4 lecciones en total.
Los signals como estado
Los signals de Angular son valores reactivos que notifican a los consumidores cuando cambian. Un signal contiene un valor y vuelve a ejecutar cualquier cálculo o plantilla que lo lea.
Almacenar signals dentro de un servicio @Injectable permite que varios componentes compartan el mismo estado reactivo.
Un signal store mínimo
Cree un servicio y mantenga el estado en un signal(). Mantenga privado el signal modificable y exponga una vista de solo lectura.
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); }
}Por qué providedIn root
providedIn: 'root' convierte el servicio en un singleton para toda la aplicación. Cada componente que lo inyecte compartirá exactamente la misma instancia del signal, por lo que el estado permanecerá sincronizado.
Leer el signal
Llame al signal como si fuera una función para leer su valor. Dentro de una plantilla, Angular realiza un seguimiento de la lectura y actualiza el DOM automáticamente cuando cambia el valor.
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 protege el estado
asReadonly() devuelve un signal que se puede leer, pero no modificar. Los componentes no pueden llamar accidentalmente a set() o update() en él, por lo que todas las modificaciones pasan por los métodos del store.
set frente a update
Use set(value) cuando tenga directamente el valor siguiente. Use update(fn) cuando el valor siguiente dependa del actual.
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); }Varios signals por store
Un store puede contener varios signals que representen distintas partes del estado. Mantenga privado cada signal modificable y exponga sus equivalentes de solo lectura.
private _items = signal<Item[]>([]);
private _loading = signal(false);
readonly items = this._items.asReadonly();
readonly loading = this._loading.asReadonly();Los métodos encapsulan la lógica
Las reglas de negocio deben residir en los métodos del store, no en los componentes. Los componentes llaman a métodos que expresan la intención, como addToCart(item), y el store decide cómo cambia el estado.
addToCart(item: Item) {
this._items.update(list => [...list, item]);
}
removeFromCart(id: string) {
this._items.update(list => list.filter(i => i.id !== id));
}No se necesitan suscripciones
A diferencia de los servicios basados en RxJS, los signal stores no necesitan subscribe() ni cancelar suscripciones manualmente. Leer un signal en una plantilla configura la reactividad y Angular la limpia cuando se destruye el componente.
Inyectar con inject()
La función inject() funciona en constructores, inicializadores de campos y funciones de fábrica. Es la forma moderna de obtener la instancia del store.
export class CartComponent {
private store = inject(CartStore);
items = this.store.items; // read-only signal
}Probar un signal store
Los signal stores son clases normales, por lo que las pruebas son sencillas: cree una instancia, llame a un método y lea sincrónicamente el valor del signal. No se necesita infraestructura asíncrona.
it('increments', () => {
const store = new CounterStore();
store.increment();
expect(store.count()).toBe(1);
});Comprobación rápida
Compruebe su comprensión de los signal stores.
Resumen
Ha aprendido a crear un store basado en signals: mantener privados los signals modificables, exponer vistas de asReadonly(), modificar el estado mediante set/update dentro de métodos e inyectar el singleton con inject(). Sin suscripciones, con pruebas sencillas y estado reactivo compartido.
Preguntas frecuentes
¿La lección «Signal Stores en servicios» es gratis?
Sí — el texto completo de «Signal Stores en servicios» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Angular Academy, actualiza a CoddyKit PRO. El curso de Angular Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Signal Stores en servicios»?
Mantener el estado de la aplicación en servicios basados en signals Practicas Angular Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Angular Academy?
No se requiere experiencia previa. Angular Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Signal Stores en servicios»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Angular Academy?
Sí. Cada lección de Angular Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Signal Stores en servicios
- Derivar el estado con computed
- Actualizar el estado de forma inmutable
- Conectar Signals y RxJS