您好,登錄后才能下訂單哦!
本篇內容主要講解“angular狀態管理器NgRx怎么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“angular狀態管理器NgRx怎么用”吧!
NgRx 是 Angular 應用中實現全局狀態管理的 Redux 架構解決方案。
@ngrx/store:全局狀態管理模塊
@ngrx/effects:處理副作用
@ngrx/store-devtools:瀏覽器調試工具,需要依賴 Redux Devtools Extension
@ngrx/schematics:命令行工具,快速生成 NgRx 文件
@ngrx/entity:提高開發者在 Reducer 中操作數據的效率
@ngrx/router-store:將路由狀態同步到全局 Store
1、下載 NgRx
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
// angular.json "cli": { "defaultCollection": "@ngrx/schematics" }
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 { createAction } from "@ngrx/store" export const increment = createAction("increment") export const decrement = createAction("decrement")
5、創建 Reducer
ng g reducer store/reducers/counter --skipTests --reducers=../index.ts
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 })) )
6、創建 Selector
ng g selector store/selectors/counter --skipTests
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)
7、組件類觸發 Action、獲取狀態
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()) } }
8、組件模板顯示狀態
<button (click)="increment()">+</button> <span>{{ count | async }}</span> <button (click)="decrement()">-</button>
1、在組件中使用 dispatch 觸發 Action 時傳遞參數,參數最終會被放置在 Action 對象中。
this.store.dispatch(increment({ count: 5 }))
2、在創建 Action Creator 函數時,獲取參數并指定參數類型。
import { createAction, props } from "@ngrx/store" export const increment = createAction("increment", props<{ count: number }>())
export declare function props<P extends object>(): Props<P>;
3、在 Reducer 中通過 Action 對象獲取參數。
export const reducer = createReducer( initialState, on(increment, (state, action) => ({ count: state.count + action.count })) )
metaReducer 是 Action -> Reducer 之間的鉤子,允許開發者對 Action 進行預處理 (在普通 Reducer 函數調用之前調用)。
function debug(reducer: ActionReducer<any>): ActionReducer<any> { return function (state, action) { return reducer(state, action) } } export const metaReducers: MetaReducer<AppState>[] = !environment.production ? [debug] : []
需求:在頁面中新增一個按鈕,點擊按鈕后延遲一秒讓數值增加。
1、在組件模板中新增一個用于異步數值增加的按鈕,按鈕被點擊后執行 increment_async
方法
<button (click)="increment_async()">async</button>
2、在組件類中新增 increment_async
方法,并在方法中觸發執行異步操作的 Action
increment_async() { this.store.dispatch(increment_async()) }
3、在 Action 文件中新增執行異步操作的 Action
export const increment_async = createAction("increment_async")
4、創建 Effect,接收 Action 并執行副作用,繼續觸發 Action
ng g effect store/effects/counter --root --module app.module.ts --skipTests
Effect 功能由 @ngrx/effects 模塊提供,所以在根模塊中需要導入相關的模塊依賴
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 })))) ) }) }
1、概述
Entity 譯為實體,實體就是集合中的一條數據。
NgRx 中提供了實體適配器對象,在實體適配器對象下面提供了各種操作集合中實體的方法,目的就是提高開發者操作實體的效率。
2、核心
1、EntityState:實體類型接口
/* { ids: [1, 2], entities: { 1: { id: 1, title: "Hello Angular" }, 2: { id: 2, title: "Hello NgRx" } } } */ export interface State extends EntityState<Todo> {}
2、createEntityAdapter: 創建實體適配器對象
3、EntityAdapter:實體適配器對象類型接口
export const adapter: EntityAdapter<Todo> = createEntityAdapter<Todo>() // 獲取初始狀態 可以傳遞對象參數 也可以不傳 // {ids: [], entities: {}} export const initialState: State = adapter.getInitialState()
3、實例方法
https://ngrx.io/guide/entity/adapter#adapter-collection-methods
4、選擇器
// 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)
1、同步路由狀態
1)引入模塊
import { StoreRouterConnectingModule } from "@ngrx/router-store" @NgModule({ imports: [ StoreRouterConnectingModule.forRoot() ] }) export class AppModule {}
2)將路由狀態集成到 Store
import * as fromRouter from "@ngrx/router-store" export interface AppState { router: fromRouter.RouterReducerState } export const reducers: ActionReducerMap<AppState> = { router: fromRouter.routerReducer }
2、創建獲取路由狀態的 Selector
// 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) } }
到此,相信大家對“angular狀態管理器NgRx怎么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。