サービス内のSignal Store
Signalベースのサービスでアプリの状態を保持します
「サービス内のSignal Store」はCoddyKit上の無料Angular Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これは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); }1つのストアに複数のシグナル
ストアには、状態の異なる部分を表す複数のシグナルを保持できます。各書き込み可能なシグナルを非公開にし、対応する読み取り専用のシグナルを公開します。
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()でシングルトンを注入する、シグナルベースのストアの構築方法を学びました。サブスクリプションは不要で、テストも簡単な共有リアクティブ状態を実現できます。
よくある質問
「サービス内のSignal Store」レッスンは無料ですか?
はい。「サービス内のSignal Store」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Angular Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Angular Academyコースには全4レッスンが含まれています。
「サービス内のSignal Store」で何を学びますか?
Signalベースのサービスでアプリの状態を保持します ブラウザで直接実行するハンズオンコードでAngular Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Angular Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAngular Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「サービス内のSignal Store」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAngular Academyレッスンでコードを書いて実行できますか?
はい。すべてのAngular Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- サービス内のSignal Store
- computedによる状態の導出
- イミュータブルな状態更新
- SignalsとRxJSの接続