Dieser Artikel vermittelt Ihnen ein detailliertes Verständnis des State Managers NgRx von Angular und stellt Ihnen die Verwendung von NgRx vor. Ich hoffe, dass er für alle hilfreich ist!
NgRx ist eine Redux-Architekturlösung für die globale Zustandsverwaltung in Angular-Anwendungen. [Verwandte Tutorial-Empfehlungen: „Angular Tutorial“]
@ngrx/store: Globales Zustandsverwaltungsmodul
@ngrx/effects: Umgang mit Nebenwirkungen
@ngrx/store-devtools : Browser-Debugging-Tools müssen sich auf die Redux Devtools-Erweiterung verlassen
@ngrx/schematics: Befehlszeilentool zum schnellen Generieren von NgRx-Dateien
@ngrx/entity: Verbessern Sie die Effizienz der Entwickler, die Daten in Reducer verarbeiten
@ngrx/router-store: Routing-Status mit dem globalen Store synchronisieren. ngrx/router-store @ngrx/store-devtools @ngrx/schematics
ng config cli.defaultCollection @ngrx/schematics
// angular.json "cli": { "defaultCollection": "@ngrx/schematics" }
3. Store erstellen
ng store State --root --module app.module.ts --statePath store --stateInterface AppState
npm install @ngrx/store @ngrx/effects @ngrx/entity @ngrx/router-store @ngrx/store-devtools @ngrx/schematics
2、配置 NgRx CLI
ng config cli.defaultCollection @ngrx/schematics
import { createAction } from "@ngrx/store" export const increment = createAction("increment") export const decrement = createAction("decrement")
3、创建 Store
ng g store State --root --module app.module.ts --statePath store --stateInterface AppState
4、创建 Action
ng g action store/actions/counter --skipTests
import { createReducer, on } from "@ngrx/store" import { decrement, increment } from "../actions/counter.actions" export const counterFeatureKey = "counter" export interface State { count: number } export const initialState: State = { count: 0 } export const reducer = createReducer( initialState, on(increment, state => ({ count: state.count + 1 })), on(decrement, state => ({ count: state.count - 1 })) )
5、创建 Reducer
ng g reducer store/reducers/counter --skipTests --reducers=../index.ts
import { createFeatureSelector, createSelector } from "@ngrx/store" import { counterFeatureKey, State } from "../reducers/counter.reducer" import { AppState } from ".." export const selectCounter = createFeatureSelector<AppState, State>(counterFeatureKey) export const selectCount = createSelector(selectCounter, state => state.count)
6、创建 Selector
ng g selector store/selectors/counter --skipTests
import { select, Store } from "@ngrx/store" import { Observable } from "rxjs" import { AppState } from "./store" import { decrement, increment } from "./store/actions/counter.actions" import { selectCount } from "./store/selectors/counter.selectors" export class AppComponent { count: Observable<number> constructor(private store: Store<AppState>) { this.count = this.store.pipe(select(selectCount)) } increment() { this.store.dispatch(increment()) } decrement() { this.store.dispatch(decrement()) } }
7、组件类触发 Action、获取状态
<button (click)="increment()">+</button> <span>{{ count | async }}</span> <button (click)="decrement()">-</button>
8、组件模板显示状态
this.store.dispatch(increment({ count: 5 }))
1、在组件中使用 dispatch 触发 Action 时传递参数,参数最终会被放置在 Action 对象中。
import { createAction, props } from "@ngrx/store" export const increment = createAction("increment", props<{ count: number }>())
2、在创建 Action Creator 函数时,获取参数并指定参数类型。
export declare function props<P extends object>(): Props<P>;
export const reducer = createReducer( initialState, on(increment, (state, action) => ({ count: state.count + action.count })) )
3、在 Reducer 中通过 Action 对象获取参数。
function debug(reducer: ActionReducer<any>): ActionReducer<any> { return function (state, action) { return reducer(state, action) } } export const metaReducers: MetaReducer<AppState>[] = !environment.production ? [debug] : []
metaReducer 是 Action -> Reducer 之间的钩子,允许开发者对 Action 进行预处理 (在普通 Reducer 函数调用之前调用)。
<button (click)="increment_async()">async</button>
需求:在页面中新增一个按钮,点击按钮后延迟一秒让数值增加。
1、在组件模板中新增一个用于异步数值增加的按钮,按钮被点击后执行 increment_async
方法
increment_async() { this.store.dispatch(increment_async()) }
2、在组件类中新增 increment_async
方法,并在方法中触发执行异步操作的 Action
export const increment_async = createAction("increment_async")
3、在 Action 文件中新增执行异步操作的 Action
import { Injectable } from "@angular/core" import { Actions, createEffect, ofType } from "@ngrx/effects" import { increment, increment_async } from "../actions/counter.actions" import { mergeMap, map } from "rxjs/operators" import { timer } from "rxjs" // createEffect // 用于创建 Effect, Effect 用于执行副作用. // 调用方法时传递回调函数, 回调函数中返回 Observable 对象, 对象中要发出副作用执行完成后要触发的 Action 对象 // 回调函数的返回值在 createEffect 方法内部被继续返回, 最终返回值被存储在了 Effect 类的属性中 // NgRx 在实例化 Effect 类后, 会订阅 Effect 类属性, 当副作用执行完成后它会获取到要触发的 Action 对象并触发这个 Action // Actions // 当组件触发 Action 时, Effect 需要通过 Actions 服务接收 Action, 所以在 Effect 类中通过 constructor 构造函数参数的方式将 Actions 服务类的实例对象注入到 Effect 类中 // Actions 服务类的实例对象为 Observable 对象, 当有 Action 被触发时, Action 对象本身会作为数据流被发出 // ofType // 对目标 Action 对象进行过滤. // 参数为目标 Action 的 Action Creator 函数 // 如果未过滤出目标 Action 对象, 本次不会继续发送数据流 // 如果过滤出目标 Action 对象, 会将 Action 对象作为数据流继续发出 @Injectable() export class CounterEffects { constructor(private actions: Actions) { // this.loadCount.subscribe(console.log) } loadCount = createEffect(() => { return this.actions.pipe( ofType(increment_async), mergeMap(() => timer(1000).pipe(map(() => increment({ count: 10 })))) ) }) }
4、创建 Effect,接收 Action 并执行副作用,继续触发 Action
ng g effect store/effects/counter --root --module app.module.ts --skipTests
4. Aktion erstellen
ng g action store/actions/counter --skipTests
/* { ids: [1, 2], entities: { 1: { id: 1, title: "Hello Angular" }, 2: { id: 2, title: "Hello NgRx" } } } */ export interface State extends EntityState<Todo> {}
5. Create Reducerng g Reducer store/reducers/counter --skipTests --reducers=../index.ts < /code></strong><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">export const adapter: EntityAdapter<Todo> = createEntityAdapter<Todo>()
// 获取初始状态 可以传递对象参数 也可以不传
// {ids: [], entities: {}}
export const initialState: State = adapter.getInitialState()</pre><div class="contentsignin">Nach dem Login kopieren</div></div></p><p>6. Selektor erstellen</p><p></p><code>ng g selector store/selectors/counter --skipTests
// selectTotal 获取数据条数
// selectAll 获取所有数据 以数组形式呈现
// selectEntities 获取实体集合 以字典形式呈现
// selectIds 获取id集合, 以数组形式呈现
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();
export const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey)
export const selectTodos = createSelector(selectTodo, selectAll)
8. Anzeigestatus der Komponentenvorlage
import { StoreRouterConnectingModule } from "@ngrx/router-store" @NgModule({ imports: [ StoreRouterConnectingModule.forRoot() ] }) export class AppModule {}
Action Payload
1 Übergeben Sie Parameter, wenn Sie den Versand in der Komponente verwenden, um eine Aktion auszulösen, und die Parameter werden schließlich im Aktionsobjekt platziert. import * as fromRouter from "@ngrx/router-store"
export interface AppState {
router: fromRouter.RouterReducerState
}
export const reducers: ActionReducerMap<AppState> = {
router: fromRouter.routerReducer
}
// router.selectors.ts import { createFeatureSelector } from "@ngrx/store" import { AppState } from ".." import { RouterReducerState, getSelectors } from "@ngrx/router-store" const selectRouter = createFeatureSelector<AppState, RouterReducerState>( "router" ) export const { // 获取和当前路由相关的信息 (路由参数、路由配置等) selectCurrentRoute, // 获取地址栏中 # 号后面的内容 selectFragment, // 获取路由查询参数 selectQueryParams, // 获取具体的某一个查询参数 selectQueryParam('name') selectQueryParam, // 获取动态路由参数 selectRouteParams, // 获取某一个具体的动态路由参数 selectRouteParam('name') selectRouteParam, // 获取路由自定义数据 selectRouteData, // 获取路由的实际访问地址 selectUrl } = getSelectors(selectRouter)
// home.component.ts import { select, Store } from "@ngrx/store" import { AppState } from "src/app/store" import { selectQueryParams } from "src/app/store/selectors/router.selectors" export class AboutComponent { constructor(private store: Store<AppState>) { this.store.pipe(select(selectQueryParams)).subscribe(console.log) } }
MetaReducermetaReducer ist ein Hook zwischen Action -> Reducer, der es Entwicklern ermöglicht, Action vorzuverarbeiten (aufgerufen, bevor die normale Reducer-Funktion aufgerufen wird). rrreee
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, führen Sie die Methode increment_async
aus > Methode und lösen Sie die Aktion aus, die die asynchrone Operation in der Methode ausführtrrreee3. Fügen Sie die Aktion hinzu, die die asynchrone Operation in der Aktionsdatei ausführtrrreee
rrreeeEntity
🎜🎜Entity wird als Entity übersetzt und Entity 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. EntityState: Entitätstypschnittstelle🎜rrreee🎜2. EntityAdapter: Entitätsadapterobjekttypschnittstelle🎜🎜🎜3 🎜 🎜🎜🎜https://ngrx.io/guide/entity/adapter#adapter-collection-methods🎜🎜🎜🎜4. Selektor🎜🎜🎜rrreeerrreee🎜🎜Router Store🎜🎜🎜🎜🎜1. Routing-Status synchronisieren🎜🎜 🎜 🎜1) Modul vorstellen 🎜rrreee🎜2) Routing-Status in Store integrieren🎜rrreee🎜🎜🎜2. Erstellen Sie einen Selektor, um den Routing-Status zu erhalten🎜🎜🎜rrreeerrreee🎜Für weitere Programmierkenntnisse besuchen Sie bitte: 🎜Programmiervideo🎜! ! 🎜Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Angular Learning State Managers NgRx. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!