Pencipta Kedai Isyarat NGRX, Marko Stanimirovic menerangkan di sini Kedai Isyarat NgRx: Pandangan Mendalam pada Pengurusan Negeri Berasaskan Isyarat dalam Sudut
Mari teroka API kedai dengan contoh kod. Kami akan menggunakan projek dengan senarai produk dan ciri penapisan.
import { signalStore } from "@ngrx/signals"; export const ProductStore = signalStore( … );
Seperti mana-mana Kedai NGRX setakat ini, terdapat keadaan awal yang boleh disediakan, menggunakan fungsi withState yang menerima literal objek, rekod atau fungsi kilang (untuk mencipta keadaan permulaan dinamik) sebagai input.
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 masuk ke dalam fungsi kilang dan kembalikan kamus kaedah dan isyarat yang dikira yang boleh diakses dengan menggunakan kedai itu. Ia juga dijalankan dalam konteks suntikan, yang memungkinkan untuk menyuntik kebergantungan ke dalamnya.
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)); }, })),
Ada kemungkinan untuk menambah berbilang ciri yang bermula dengan "dengan" tetapi mereka boleh mengakses hanya apa yang ditakrifkan sebelum mereka.
signalStoreFeature - digunakan untuk memanjangkan kefungsian kedai.
Kedai boleh menjadi rumit dan sukar untuk diurus untuk aplikasi perusahaan besar. Apabila menulis ciri dan komponen untuk projek, lebih baik dan lebih terperinci pembahagian, lebih mudah untuk mengurus, mengekalkan kod dan menulis ujian untuknya.
Walau bagaimanapun, memandangkan API yang SignalStore sediakan kedai boleh menjadi sukar untuk diurus melainkan kod dipecahkan dengan sewajarnya. signalStoreFeature sesuai untuk mengekstrak kefungsian tertentu bagi sesuatu ciri (atau komponen) ke dalam fungsi boleh diuji kendiri yang berpotensi (dan idealnya) boleh digunakan semula di kedai lain.
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); }, })), ); }
Kini contoh signalStoreFeature yang menunjukkan kemungkinan untuk menggunakan semula signalStoreFeature(s) merentas berbilang kedai.
import { patchState, signalStoreFeature, withMethods } daripada "@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(), );
Memandangkan begitu mudah untuk dilanjutkan, sudah ada pakej utiliti yang dipanggil ngrx-toolkit yang bertujuan untuk menambah alatan berguna pada Signal Stores.
{ providedIn: ‘root’ } atau dalam tatasusunan penyedia Komponen, Perkhidmatan, Arahan, dsb.
Ia masih perlu dibuktikan sejauh mana ia boleh dipercayai untuk aplikasi yang lebih besar, terutamanya apabila digunakan sebagai kedai global.
Buat masa ini saya fikir ia adalah tambahan yang bagus kepada API Isyarat lalai, menjadikannya pilihan yang baik untuk mengurus:
https://www.stefanos-lignos.dev/posts/ngrx-signals-store
https://www.angulararchitects.io/blog/the-new-ngrx-signal-store-for-angular-2-1-flavors/ (kumpulan 4 artikel mengenai topik)
https://ngrx.io/guide/signals
Atas ialah kandungan terperinci The Signal Store dari NGRX - pecahan konsep utama. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!