Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis des Angular-Statusmanagers NgRx und stellt Ihnen die Verwendung von NgRx vor. Ich hoffe, er wird Ihnen hilfreich sein!
NgRx ist eine Redux-Architekturlösung für die globale Zustandsverwaltung in Angular-Anwendungen. [Empfohlene verwandte Tutorials: „Angular-Tutorial“]
@ngrx/store: Globales Statusverwaltungsmodul
@ngrx/effects: Umgang mit Nebenwirkungen
@ngrx/store-devtools: Browser-Debugging-Tool, muss auf der Redux Devtools-Erweiterung basieren
@ngrx/schematics: Befehlszeilentool zum schnellen Generieren von NgRx-Dateien
@ngrx/entity: Verbessern Sie die Effizienz der Entwickler bei der Verarbeitung von Daten in Reducer
@ngrx/router-store: Routing-Status mit dem globalen Store synchronisieren
1. Laden Sie NgRx herunter
npm install @ngrx/store @ngrx/effects @ngrx/entity @ngrx/router-store @ngrx/store-devtools @ngrx/schematics
2. Konfigurieren Sie die NgRx-CLI
ng config cli.defaultCollection @ngrx/schematics
// angle.json "cli": { „defaultCollection“: „@ngrx/schematics“ }
3. Shop erstellen
ng g store State --root --module app.module.ts --statePath store --stateInterface AppState
4. Aktion erstellen
ng g action store/actions/counter --skipTests
importiere {createAction} aus „@ngrx/store“ export const inkrement = createAction("inkrement") export const dekrement = createAction("dekrementieren")
5. Reduzierer erstellen
ng g reducer store/reducers/counter --skipTests --reducers=../index.ts
import { createReducer, on } from „@ngrx/store“ importiere { dekrementieren, inkrementieren } aus „../actions/counter.actions“ export const counterFeatureKey = "counter" Exportschnittstellenstatus { count: Zahl } export const initialState: State = { Anzahl: 0 } export const Reducer = createReducer( Anfangszustand, on(increment, state => ({ count: state.count + 1 })), on(decrement, state => ({ count: state.count - 1 })) )
6. Selektor erstellen
ng g selector store/selectors/counter --skipTests
import { createFeatureSelector, createSelector } aus „@ngrx/store“ importiere { counterFeatureKey, State } aus „../reducers/counter.reducer“ importiere { AppState } aus „..“ export const selectCounter = createFeatureSelector<AppState, State>(counterFeatureKey) export const selectCount = createSelector(selectCounter, state => state.count)
7. Die Komponentenklasse löst eine Aktion aus und erhält den Status
import { select, Store } from „@ngrx/store“ importiere { Observable } aus „rxjs“ importiere { AppState } aus „./store“ importiere { dekrementieren, inkrementieren } aus „./store/actions/counter.actions“ importiere { selectCount } aus „./store/selectors/counter.selectors“ Exportklasse AppComponent { count: Observable<Nummer> Konstruktor(privater Speicher: Store<AppState>) { this.count = this.store.pipe(select(selectCount)) } inkrement() { this.store.dispatch(increment()) } dekrementieren() { this.store.dispatch(decrement()) } }
8. Anzeigestatus der Komponentenvorlage
<button (click)="increment()">+</button> <span>{{ count |. async }}</span> <button (click)="decrement()">-</button>
1. Verwenden Sie den Dispatch in der Komponente, um beim Auslösen einer Aktion Parameter zu übergeben. Die Parameter werden schließlich im Aktionsobjekt platziert.
this.store.dispatch(increment({ count: 5 }))
2. Rufen Sie beim Erstellen der Action Creator-Funktion die Parameter ab und geben Sie den Parametertyp an.
importiere { createAction, props } aus „@ngrx/store“ export const increment = createAction("increment", props<{ count: number }>())
Export-Deklarationsfunktion props<P erweitert Objekt>(): Props<P>;
3. Parameter über das Action-Objekt im Reducer abrufen.
export const Reducer = createReducer( Anfangszustand, on(inkrementieren, (Zustand, Aktion) => ({ count: state.count + action.count })) )
metaReducer ist ein Hook zwischen Action -> Reducer und ermöglicht Entwicklern die Vorverarbeitung von Action (wird vor gewöhnlichen Reducer-Funktionsaufrufen aufgerufen).
function debug(reducer: ActionReducer<any>): ActionReducer<any> { Rückgabefunktion (Zustand, Aktion) { Rückgabereduzierer (Zustand, Aktion) } } export const metaReducers: MetaReducer<AppState>[] = !environment.produktion ?[debuggen] : []
Anforderung: Fügen Sie der Seite eine Schaltfläche hinzu. Warten Sie nach dem Klicken auf die Schaltfläche eine Sekunde, bis sich der Wert erhöht.
1. Fügen Sie eine Schaltfläche für die asynchrone Werterhöhung in der Komponentenvorlage hinzu. Nachdem Sie auf die Schaltfläche geklickt haben, wird die Methode increment_async
ausgeführt.
<button (click)="increment_async()">async</button>
2. Fügen Sie die Methode increment_async
zur Komponentenklasse hinzu und lösen Sie die Aktion aus, um asynchrone Vorgänge in der Methode auszuführen.
increment_async() { this.store.dispatch(increment_async()) }
3. Fügen Sie eine Aktion hinzu, um asynchrone Vorgänge in der Aktionsdatei auszuführen.
export const increment_async = createAction("increment_async")
4. Erstellen Sie einen Effekt, empfangen Sie eine Aktion, führen Sie Nebenwirkungen aus und lösen Sie weiterhin eine Aktion aus
ng g effect store/effects/counter --root --module app.module.ts --skipTests
Die Effect-Funktion wird vom Modul @ngrx/effects bereitgestellt, daher müssen die relevanten Modulabhängigkeiten in das Root-Modul importiert werden.
{Injectable} aus „@angular/core“ importieren importiere { Actions, createEffect, ofType } aus „@ngrx/effects“ import { inkrement, inkrement_async } aus „../actions/counter.actions“ importiere { mergeMap, map } aus „rxjs/operators“ {timer} aus „rxjs“ importieren // createEffect // Wird zum Erstellen von Effekten verwendet. Mit Effekt werden Nebeneffekte ausgeführt. // Übergeben Sie die Rückruffunktion beim Aufrufen der Methode und geben Sie das Observable-Objekt in der Rückruffunktion zurück. Das Aktionsobjekt, das nach der Ausführung der Nebeneffekte ausgelöst werden soll. // Der Rückgabewert der Rückruffunktion wird weiterhin innerhalb von createEffect zurückgegeben Methode, und der endgültige Rückgabewert wird in den Eigenschaften der Effect-Klasse gespeichert // Nach der Instanziierung der Effect-Klasse abonniert NgRx die Eigenschaften der Effect-Klasse. Wenn die Nebeneffekte abgeschlossen sind, erhält es das auszulösende Action-Objekt und die Aktion auslösen. //Aktionen // Wenn eine Komponente eine Aktion auslöst, muss der Effekt die Aktion über den Actions-Dienst empfangen. Daher wird in der Effect-Klasse das Instanzobjekt der Actions-Dienstklasse über den Konstruktorparameter // in die Effect-Klasse eingefügt Das Objekt der Actions-Dienstklasse ist ein Observable-Objekt. Wenn eine Aktion ausgelöst wird, wird das Aktionsobjekt selbst als Datenstrom // ofType ausgegeben // Filtern Sie das Ziel-Aktionsobjekt. // Der Parameter ist die Action Creator-Funktion der Zielaktion // Wenn das Ziel-Aktionsobjekt nicht herausgefiltert wird, wird der Datenstrom diesmal nicht weiter gesendet // Wenn das Ziel-Aktionsobjekt herausgefiltert wird, das Aktionsobjekt wird weiterhin als Datenstrom gesendet @Injectable() Exportklasse CounterEffects { Konstruktor(private Aktionen: Aktionen) { // this.loadCount.subscribe(console.log) } LoadCount = createEffect(() => { gib this.actions.pipe( zurück ofType(increment_async), mergeMap(() => timer(1000).pipe(map(() => increment({ count: 10 })))) ) }) }
1. Übersicht
Entität wird als Entität übersetzt, und Entität ist ein Datenelement in der Sammlung.
NgRx stellt Entitätsadapterobjekte bereit. Unter den Entitätsadapterobjekten werden verschiedene Methoden zum Betreiben von Entitäten in der Sammlung bereitgestellt. Der Zweck besteht darin, die Effizienz von Entwicklern beim Betreiben von Entitäten zu verbessern.
2. Kern
1. EntityState: Entitätstypschnittstelle
/* { IDs: [1, 2], Entitäten: { 1: { id: 1, title: „Hello Angular“ }, 2: { id: 2, title: „Hallo NgRx“ } } } */ Exportschnittstelle State erweitert EntityState<Todo> {}
2. createEntityAdapter: Entitätsadapterobjekt erstellen
3. EntityAdapter: Entity-Adapter-Objekttypschnittstelle
Const-Adapter exportieren: EntityAdapter<Todo> = createEntityAdapter<Todo>() // Den Anfangszustand abrufen. Sie können Objektparameter übergeben oder nicht. // {ids: [], entities: {}} export const initialState: State = adapter.getInitialState()
3. Instanzmethode
https://ngrx.io/guide/entity/adapter#adapter-collection-methods
4. Auswahl
// selectTotal ruft die Anzahl der Datenelemente ab // selectAll ruft alle Daten ab und präsentiert sie in Form eines Arrays // selectEntities ruft die Entitätssammlung ab und präsentiert sie in Form eines Wörterbuchs // selectIds ruft die ID-Sammlung ab und präsentiert sie es in Form eines Arrays const { selectIds, selectEntities, selectAll, selectTotal } = adapter .getSelectors();
export const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey) export const selectTodos = createSelector(selectTodo, selectAll)
1. Routing-Status synchronisieren
1) Module vorstellen
importiere { StoreRouterConnectingModule } aus „@ngrx/router-store“ @NgModule({ Importe: [ StoreRouterConnectingModule.forRoot() ] }) Klasse AppModule {} exportieren
2) Routing-Status in Store integrieren
* als fromRouter aus „@ngrx/router-store“ importieren Exportschnittstelle AppState { Router: fromRouter.RouterReducerState } Const-Reduzierer exportieren: ActionReducerMap<AppState> = { Router: fromRouter.routerReducer }
2. Erstellen Sie einen Selektor, um den Routing-Status zu erhalten
// router.selectors.ts importiere { createFeatureSelector } aus „@ngrx/store“ importiere { AppState } aus „..“ importiere { RouterReducerState, getSelectors } aus „@ngrx/router-store“ const selectRouter = createFeatureSelector<AppState, RouterReducerState>( „Router“ ) Export const { // Informationen zur aktuellen Route abrufen (Routing-Parameter, Routing-Konfiguration usw.) selectCurrentRoute, // Den Inhalt nach der #-Nummer in der Adressleiste abrufen selectFragment, // Routing-Abfrageparameter abrufen selectQueryParams, // Einen bestimmten Abfrageparameter abrufen selectQueryParam('name') selectQueryParam, // Dynamische Routing-Parameter abrufen selectRouteParams, // Einen bestimmten dynamischen Routing-Parameter abrufen selectRouteParam('name') selectRouteParam, // Benutzerdefinierte Routendaten abrufen selectRouteData, // Die tatsächliche Zugriffsadresse der Route abrufen selectUrl } = getSelectors(selectRouter)
// home.component.ts import { select, Store } from „@ngrx/store“ {AppState} aus „src/app/store“ importieren importiere {selectQueryParams} aus „src/app/store/selectors/router.selectors“ Klasse AboutComponent { exportieren Konstruktor(privater Speicher: Store<AppState>) { this.store.pipe(select(selectQueryParams)).subscribe(console.log) } }