ホームページ  >  記事  >  ウェブフロントエンド  >  Angular Learning State Manager NgRx の詳細な説明

Angular Learning State Manager NgRx の詳細な説明

青灯夜游
青灯夜游転載
2022-05-25 11:01:202525ブラウズ

この記事では、angular のステートマネージャーである NgRx について深く理解し、NgRx の使用方法を紹介します。

Angular Learning State Manager NgRx の詳細な説明

NgRx は、Angular アプリケーションのグローバル状態管理のための Redux アーキテクチャ ソリューションです。 [関連チュートリアルの推奨事項: "angular チュートリアル"]

Angular Learning State Manager NgRx の詳細な説明

  • ##@ngrx/store: グローバル状態管理モジュール

  • @ngrx/messages: 副作用の処理

  • @ngrx/store-devtools: ブラウザ デバッグ ツール、Redux Devtools Extension に依存する必要があります

  • @ngrx/schematics: NgRx ファイルを迅速に生成するコマンド ライン ツール

  • @ngrx/entity: Reducer でデータを操作する開発者の効率を向上させます

  • #@ngrx/router-store: ルーティング ステータスをグローバル ストアに同期します
  • ##クイック スタート

1. NgRx

npm install @ngrx/store @ngrx/Effects @ngrx/entity @ngrx/router-store @ngrx/store-devtools @ngrx/schematic

をダウンロードします

2. NgRx CLI

ng config cli.defaultCollection @ngrx/schematics

// angular.json
"cli": {
  "defaultCollection": "@ngrx/schematics"
}
3 を設定します。ストアの作成

#ng g ストア状態 --root --module app.module.ts --statePath ストア --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 raiser 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. セレクターの作成

#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. コンポーネント クラスがアクションをトリガーし、ステータスを取得します

<pre class="brush:js;toolbar:false;">import { select, Store } from &quot;@ngrx/store&quot; import { Observable } from &quot;rxjs&quot; import { AppState } from &quot;./store&quot; import { decrement, increment } from &quot;./store/actions/counter.actions&quot; import { selectCount } from &quot;./store/selectors/counter.selectors&quot; export class AppComponent { count: Observable&lt;number&gt; constructor(private store: Store&lt;AppState&gt;) { this.count = this.store.pipe(select(selectCount)) } increment() { this.store.dispatch(increment()) } decrement() { this.store.dispatch(decrement()) } }</pre># #8. コンポーネント テンプレートの表示ステータス

<button (click)="increment()">+</button>
<span>{{ count | async }}</span>
<button (click)="decrement()">-</button>
アクション ペイロード

1. アクションをトリガーするときにコンポーネントでディスパッチを使用してパラメータを渡すと、パラメータは最終的に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

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 秒待って値を増やします。

1. コンポーネント テンプレートに非同期値増加用のボタンを追加します。ボタンをクリックすると、

increment_async メソッド
<button (click)="increment_async()">async</button>

2. 新しいボタンをコンポーネント テンプレートに追加します。コンポーネント クラス

increment_async

メソッドを追加し、メソッド内でアクション

increment_async() {
  this.store.dispatch(increment_async())
}
をトリガーして非同期操作を実行します。 3. アクション

export const increment_async = createAction("increment_async")
をアクション ファイルに追加します。 4. エフェクトを作成し、アクションを受け取り、サイドエフェクトを実行し、アクションをトリガーし続けます

ng g エフェクトストア/エフェクト/カウンター --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 }))))
    )
  })
}

Entity# にインポートする必要があります。

1、概要

##Entity はエンティティとして翻訳され、エンティティはコレクション内のデータの一部です。

NgRx はエンティティ アダプタ オブジェクトを提供しており、エンティティ アダプタ オブジェクトの下には、コレクション内のエンティティを操作するためのさまざまなメソッドが提供されており、開発者のエンティティ操作の効率を向上させることを目的としています。

2. Core

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();
rrree

ルーター ストア

1. ルーティング ステータスを同期する

1) モジュールを導入します
export const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey)
export const selectTodos = createSelector(selectTodo, selectAll)
2) ルーティング ステータスをストアに統合します

import { StoreRouterConnectingModule } from "@ngrx/router-store"

@NgModule({
  imports: [
    StoreRouterConnectingModule.forRoot()
  ]
})
export class AppModule {}

2. ルーティング ステータスを取得するセレクターを作成します

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(&#39;name&#39;)
  selectQueryParam,
  // 获取动态路由参数
  selectRouteParams,
 	// 获取某一个具体的动态路由参数 selectRouteParam(&#39;name&#39;)
  selectRouteParam,
  // 获取路由自定义数据
  selectRouteData,
  // 获取路由的实际访问地址
  selectUrl
} = getSelectors(selectRouter)

プログラミング関連の知識の詳細については、

プログラミング ビデオ

を参照してください。 !

以上がAngular Learning State Manager NgRx の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。