NGRX Signal Store の作成者である Marko Stanimirovic が、NgRx SignalStore: Angular での信号ベースの状態管理の詳細について説明しています
コード例を使用してストアの API を調べてみましょう。製品のリストとフィルタリング機能を含むプロジェクトを使用します。
import { signalStore } from "@ngrx/signals"; export const ProductStore = signalStore( … );
これまでの他の NGRX ストアと同様に、オブジェクト リテラル、レコード、またはファクトリ関数 (動的な初期状態を作成するため) を入力として受け入れる関数 withState を使用して、提供できる初期状態があります。
import { signalStore, withState } from "@ngrx/signals"; const initialProductState: ProductState = { products: [] }; export const ProductStore = signalStore( withState(initialProductState); );
import { signalStore, withComputed, withState } from "@ngrx/signals"; export const ProductStore = signalStore( withState(initialProductState), withComputed(({products}) => ({ averagePrice: computed(() => { const total = products().reduce((acc, p) => acc + p.price, 0); return total / products().length; }) })),
import { signalStore, withComputed, withState, withMethods } from "@ngrx/signals"; export const ProductStore = signalStore( withState(initialProductState), withComputed(({products}) => ({ averagePrice: computed(() => { const total = products().reduce((acc, p) => acc + p.price, 0); return total / products().length; }) })), // CRUD operations withMethods((store, productService = inject(ProductService), ) => ({ loadProducts: () => { const products = toSignal(productService.loadProducts()) patchState(store, { products: products() }) }, addProduct: (product: Product) => { patchState(store, { products: [...store.products(), product] }); }, // ... })),
withMethods & withComputed はファクトリ関数を取得し、メソッドと計算された信号の辞書を返します。店。また、それらは注入コンテキストでも実行されるため、依存関係を注入することが可能になります。
import { withHooks } from "@ngrx/signals"; export const ProductStore = signalStore( withHooks((store) => ({ onInit() { // Load products when the store is initialized store.loadProducts(); }, })), );
export const ProductStoreWithEntities = signalStore( withEntities<Product>(), // CRUD operations withMethods((store, productService = inject(ProductService), ) => ({ loadProducts: () => { const products = toSignal(productService.loadProducts())(); patchState(store, setAllEntities(products || [])); }, updateProduct: (product: Product) => { productService.updateProduct(product); patchState(store, setEntity(product)); }, })),
「with」で始まる複数の機能を追加することができますが、アクセスできるのはその前に定義された機能のみです。
signalStoreFeature - ストアの機能を拡張するために使用されます。
大規模なエンタープライズ アプリケーションの場合、ストアは複雑になり、管理が困難になる場合があります。プロジェクトの機能とコンポーネントを作成する場合、分割がより適切かつ細分化されるほど、コードの管理、保守、テストの作成が容易になります。
ただし、SignalStore が提供する API を考慮すると、コードをそれに応じて分割しない限り、ストアの管理が困難になる可能性があります。 signalStoreFeature は、機能 (またはコンポーネント) の特定の機能を抽出して、潜在的に (そして理想的には) 他のストアで再利用できるスタンドアロンのテスト可能な関数に抽出するのに適しています。
export const ProductStore = signalStore( // previous defined state and methods // Externalizing filtering options withFilteringOptions(), ); export function withFilteringOptions() { return signalStoreFeature( // Filtering operations withMethods(() => ({ getProductsBetweenPriceRange: (lowPrice: number, highPrice: number, products: Array<Product>, ) => { return products.filter(p => p.price >= lowPrice && p.price <= highPrice); }, getProductsByCategory: (category: string, products: Array<Product>) => { return products.filter(p => p.category === category); }, })), ); }
次に、複数のストア間で signalStoreFeature を再利用する可能性を示す signalStoreFeature の例です。
import { patchState, signalStoreFeature, withMethods } from "@ngrx/signals";
export function withCrudOperations() { return signalStoreFeature( withMethods((store) => ({ load: (crudService: CrudOperations) => crudService.load(), update: (crudableObject: CRUD, crudService: CrudOperations) => { crudService.update(crudableObject); patchState(store, setEntity(crudableObject)); }, }), )); } export interface CrudOperations { load(): void; update(crudableObject: CRUD): void; } // Product & Customer services must extend the same interface. export class ProductService implements CrudOperations { load(): void { console.log('load products'); } update(): void { console.log('update products'); } } export class CustomerService implements CrudOperations { load(): void { console.log('load customers'); } update(): void { console.log('update customers'); } } // and now let’s add this feature in our stores export const ProductStore = signalStore( withCrudOperations(), ); export const CustomerStore = signalStore( withCrudOperations(), );
拡張が簡単なため、Signal Store に便利なツールを追加するための ngrx-toolkit と呼ばれるユーティリティ パッケージがすでに存在します。
{ providedIn: ‘root’ } またはコンポーネント、サービス、ディレクティブなどのプロバイダー配列内。
大規模なアプリケーション、特にグローバル ストアとして適用される場合にどの程度信頼できるかはまだ証明されていません。
今のところ、これはデフォルトの Signal API への優れた追加であり、以下を管理するための良いオプションになると思います。
https://www.stefanos-lignos.dev/posts/ngrx-signals-store
https://www.angulararchitects.io/blog/the-new-ngrx-signal-store-for-angular-2-1-flavors/ (このトピックに関する 4 つの記事のグループ)
https://ngrx.io/guide/signals
以上がNGRX の Signal Store - 主要コンセプトの内訳の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。