Maison > interface Web > js tutoriel > Explication détaillée du gestionnaire d'état d'apprentissage angulaire NgRx

Explication détaillée du gestionnaire d'état d'apprentissage angulaire NgRx

青灯夜游
Libérer: 2022-05-25 11:01:20
avant
2676 Les gens l'ont consulté

Cet article vous donnera une compréhension approfondie du gestionnaire d'état de angular, NgRx, et vous présentera comment utiliser NgRx. J'espère qu'il sera utile à tout le monde !

Explication détaillée du gestionnaire d'état d'apprentissage angulaire NgRx

NgRx est une solution d'architecture Redux pour la gestion globale de l'état dans les applications angulaires. [Recommandations de tutoriel associées : "tutoriel angulaire"]

Explication détaillée du gestionnaire détat dapprentissage angulaire NgRx

  • @ngrx/store : Module de gestion de l'état global

  • @ngrx/effects : Gestion des effets secondaires

  • @ngrx/store-devtools : Les outils de débogage du navigateur doivent s'appuyer sur Redux Devtools Extension

  • @ngrx/schematics : outil de ligne de commande pour générer rapidement des fichiers NgRx

  • @ngrx/entity : améliorer l'efficacité des développeurs exploitant les données dans Réducteur

  • @ngrx/router-store : Synchronisez l'état de routage avec le Store global

Démarrage rapide

1 Téléchargez NgRx

npm install @ngrx/store @ngrx/effects @ngrx/entity @. ngrx/router-store @ngrx/store-devtools @ngrx/schematicsnpm 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"
}
Copier après la connexion

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")
Copier après la connexion

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 }))
)
Copier après la connexion

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)
Copier après la connexion

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())
  }
}
Copier après la connexion

8、组件模板显示状态

<button (click)="increment()">+</button>
<span>{{ count | async }}</span>
<button (click)="decrement()">-</button>
Copier après la connexion

Action Payload

1、在组件中使用 dispatch 触发 Action 时传递参数,参数最终会被放置在 Action 对象中。

this.store.dispatch(increment({ count: 5 }))
Copier après la connexion

2、在创建 Action Creator 函数时,获取参数并指定参数类型。

import { createAction, props } from "@ngrx/store"
export const increment = createAction("increment", props<{ count: number }>())
Copier après la connexion
export declare function props<P extends object>(): Props<P>;
Copier après la connexion

3、在 Reducer 中通过 Action 对象获取参数。

export const reducer = createReducer(
  initialState,
  on(increment, (state, action) => ({ count: state.count + action.count }))
)
Copier après la connexion

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]
  : []
Copier après la connexion

Effect

需求:在页面中新增一个按钮,点击按钮后延迟一秒让数值增加。

1、在组件模板中新增一个用于异步数值增加的按钮,按钮被点击后执行 increment_async 方法

<button (click)="increment_async()">async</button>
Copier après la connexion

2、在组件类中新增 increment_async 方法,并在方法中触发执行异步操作的 Action

increment_async() {
  this.store.dispatch(increment_async())
}
Copier après la connexion

3、在 Action 文件中新增执行异步操作的 Action

export const increment_async = createAction("increment_async")
Copier après la connexion

4、创建 Effect,接收 Action 并执行副作用,继续触发 Action

ng g effect store/effects/counter --root --module app.module.ts --skipTests

2. Configurez NgRx CLI

ng config cli.defaultCollection @ngrx/schematics
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 }))))
    )
  })
}
Copier après la connexion

3. Créer un magasinng store State --root --module app.module.ts --statePath store --stateInterface AppState

4 Créer une action

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> {}
Copier après la connexion
5. Créer un réducteur

ng g réducteur store/reducers/counter --skipTests --reducers=../index.ts < /code><p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:js;toolbar:false;">export const adapter: EntityAdapter&lt;Todo&gt; = createEntityAdapter&lt;Todo&gt;() // 获取初始状态 可以传递对象参数 也可以不传 // {ids: [], entities: {}} export const initialState: State = adapter.getInitialState()</pre><div class="contentsignin">Copier après la connexion</div></div></p><p>6. Créer un sélecteur</p><p></p><code>ng g selector store/selectors/counter --skipTests

// selectTotal 获取数据条数
// selectAll 获取所有数据 以数组形式呈现
// selectEntities 获取实体集合 以字典形式呈现
// selectIds 获取id集合, 以数组形式呈现
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();
Copier après la connexion
7. 8. Statut d'affichage du modèle de composant
export const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey)
export const selectTodos = createSelector(selectTodo, selectAll)
Copier après la connexion

Action Payload

1. Transmettez les paramètres lors de l'utilisation de la répartition dans le composant pour déclencher l'action, et les paramètres seront finalement placés dans l'objet Action.

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

@NgModule({
  imports: [
    StoreRouterConnectingModule.forRoot()
  ]
})
export class AppModule {}
Copier après la connexion
2. Lors de la création de la fonction Action Creator, récupérez les paramètres et spécifiez le type de paramètre.
import * as fromRouter from "@ngrx/router-store"

export interface AppState {
  router: fromRouter.RouterReducerState
}
export const reducers: ActionReducerMap<AppState> = {
  router: fromRouter.routerReducer
}
Copier après la connexion
// 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)
Copier après la connexion

3. Obtenez les paramètres via l'objet Action dans Réducteur.

// 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)
  }
}
Copier après la connexion
MetaReducer

metaReducer est un hook entre Action -> Réducteur, permettant aux développeurs de prétraiter l'action (appelée avant l'appel de la fonction normale du réducteur). rrreeeEffet

Exigence : Ajoutez un bouton à la page, et après avoir cliqué sur le bouton, attendez une seconde pour augmenter la valeur.

1. Ajoutez un bouton pour l'incrémentation de valeur asynchrone dans le modèle de composant. Une fois le bouton cliqué, exécutez la méthode increment_async

rrreee2. Ajoutez increment_async dans le code de la classe du composant. > méthode, et déclenchez l'action qui effectue l'opération asynchrone dans la méthode<span style="font-size: 18px;">rrreee</span>3. Ajoutez l'action qui effectue l'opération asynchrone dans le fichier d'actionrrreee

4, recevez l'action et exécutez les effets secondaires, et continuez à déclencher l'Action

ng g effect store/effects/counter --root --module app.module.ts --skipTests

La fonction d'effet est fournie par le module @ngrx/effects, donc les modules associés doivent être importés dans le module racine Dépend de 🎜rrreee🎜🎜Entity🎜🎜🎜🎜🎜1 Présentation🎜🎜🎜🎜L'entité est traduite par entité et l'entité est une donnée de la collection. 🎜🎜NgRx fournit des objets adaptateur d'entité. Sous les objets adaptateur d'entité, diverses méthodes pour exploiter les entités de la collection sont fournies. Le but est d'améliorer l'efficacité des développeurs exploitant les entités. 🎜🎜🎜🎜2. Core🎜🎜🎜🎜1. EntityState : interface de type d'entité🎜rrreee🎜2. createEntityAdapter : créer un objet adaptateur d'entité🎜🎜3. Méthode d'instance🎜 🎜🎜🎜https://ngrx.io/guide/entity/adapter#adapter-collection-methods🎜🎜🎜🎜4 Sélecteur🎜🎜🎜rrreeerrreee🎜🎜Router Store🎜🎜🎜🎜🎜1. 🎜 🎜1) Présentez le module 🎜rrreee🎜2) Intégrez le statut de routage dans Store🎜rrreee🎜🎜🎜2 Créez un sélecteur pour obtenir le statut de routage🎜🎜🎜rrreeerrreee🎜Pour plus de connaissances sur la programmation, veuillez visiter : 🎜Vidéo de programmation🎜 ! ! 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:csdn.net
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal