Heim > Web-Frontend > js-Tutorial > Hauptteil

Detaillierte Erläuterung des Angular Learning State Managers NgRx

青灯夜游
Freigeben: 2022-05-25 11:01:20
nach vorne
2609 Leute haben es durchsucht

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!

Detaillierte Erläuterung des Angular Learning State Managers NgRx

NgRx ist eine Redux-Architekturlösung für die globale Zustandsverwaltung in Angular-Anwendungen. [Verwandte Tutorial-Empfehlungen: „Angular Tutorial“]

Detaillierte Erläuterung des Angular Learning State Managers NgRx

  • @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

2. Konfigurieren Sie NgRx CLI

ng config cli.defaultCollection @ngrx/schematics

// angular.json
"cli": {
  "defaultCollection": "@ngrx/schematics"
}
Nach dem Login kopieren

3. Store erstellen

ng store State --root --module app.module.ts --statePath store --stateInterface AppStatenpm 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")
Nach dem Login kopieren

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 }))
)
Nach dem Login kopieren

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)
Nach dem Login kopieren

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())
  }
}
Nach dem Login kopieren

7、组件类触发 Action、获取状态

<button (click)="increment()">+</button>
<span>{{ count | async }}</span>
<button (click)="decrement()">-</button>
Nach dem Login kopieren

8、组件模板显示状态

this.store.dispatch(increment({ count: 5 }))
Nach dem Login kopieren

Action Payload

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

import { createAction, props } from "@ngrx/store"
export const increment = createAction("increment", props<{ count: number }>())
Nach dem Login kopieren

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

export declare function props<P extends object>(): Props<P>;
Nach dem Login kopieren
export const reducer = createReducer(
  initialState,
  on(increment, (state, action) => ({ count: state.count + action.count }))
)
Nach dem Login kopieren

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]
  : []
Nach dem Login kopieren

MetaReducer

metaReducer 是 Action -> Reducer 之间的钩子,允许开发者对 Action 进行预处理 (在普通 Reducer 函数调用之前调用)。

<button (click)="increment_async()">async</button>
Nach dem Login kopieren

Effect

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

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

increment_async() {
  this.store.dispatch(increment_async())
}
Nach dem Login kopieren

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

export const increment_async = createAction("increment_async")
Nach dem Login kopieren

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 }))))
    )
  })
}
Nach dem Login kopieren

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> {}
Nach dem Login kopieren

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&lt;Todo&gt; = createEntityAdapter&lt;Todo&gt;() // 获取初始状态 可以传递对象参数 也可以不传 // {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();
Nach dem Login kopieren
7. Komponentenklasse löst Aktion aus und erhält Status
export const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey)
export const selectTodos = createSelector(selectTodo, selectAll)
Nach dem Login kopieren

8. Anzeigestatus der Komponentenvorlage

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

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

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
}
Nach dem Login kopieren
2. Rufen Sie beim Erstellen der Action Creator-Funktion die Parameter ab und geben Sie den Parametertyp an.
// 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)
Nach dem Login kopieren
rrree

3. Parameter über das Action-Objekt im Reducer abrufen.

// 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)
  }
}
Nach dem Login kopieren

MetaReducermetaReducer ist ein Hook zwischen Action -> Reducer, der es Entwicklern ermöglicht, Action vorzuverarbeiten (aufgerufen, bevor die normale Reducer-Funktion aufgerufen wird). rrreee

Effekt

Anforderung: Fügen Sie der Seite eine Schaltfläche hinzu und verzögern Sie nach dem Klicken auf die Schaltfläche eine Sekunde, um den Wert zu erhöhen.

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

4, empfangen Sie die Aktion und führen Sie die Nebenwirkungen aus weiterhin die Aktion auslösen

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

Die Effektfunktion wird vom @ngrx/effects-Modul bereitgestellt, also Zugehörige Module müssen in das Stammmodul importiert werden. Hängt von

rrreeeEntity

1 ab. Übersicht

🎜🎜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!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage