각도 학습 상태 관리자 NgRx에 대한 자세한 설명

青灯夜游
풀어 주다: 2022-05-25 11:01:20
앞으로
2610명이 탐색했습니다.

이 글은 angular의 상태 관리자 NgRx에 대한 심층적인 이해를 제공하고, NgRx 사용법을 소개하는 글이 모든 분들께 도움이 되기를 바랍니다!

각도 학습 상태 관리자 NgRx에 대한 자세한 설명

NgRx는 Angular 애플리케이션의 전역 상태 관리를 위한 Redux 아키텍처 솔루션입니다. [관련 튜토리얼 권장사항: "angular tutorial"]

각도 학습 상태 관리자 NgRx에 대한 자세한 설명

  • @ngrx/store: 전역 상태 관리 모듈

  • @ngrx/events: 부작용 처리

  • @ngrx/store-devtools : 브라우저 디버깅 도구는 Redux Devtools Extension

  • @ngrx/schematics에 의존해야 함: NgRx 파일을 빠르게 생성하는 명령줄 도구

  • @ngrx/entity: Reducer에서 데이터를 운영하는 개발자의 효율성 향상

  • @ngrx/router-store: 라우팅 상태를 전역 Store

빠른 시작

1에 동기화합니다. NgRx

npm install @ngrx/store @ngrx/efficent @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"
}
로그인 후 복사

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>
로그인 후 복사

Action Payload

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

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]
  : []
로그인 후 복사

Effect

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

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

2. 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 }))))
    )
  })
}
로그인 후 복사

구성 3. Storeng store State --root --module app.module.ts --statePath store --stateInterface AppState

4. Create 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> {}
로그인 후 복사
5. 리듀서 생성

ng g 리듀서 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">로그인 후 복사</div></div></p><p>6. 선택기 만들기</p><p></p><code>ng g 선택기 store/selectors/counter --skipTests

// selectTotal 获取数据条数
// selectAll 获取所有数据 以数组形式呈现
// selectEntities 获取实体集合 以字典形式呈现
// selectIds 获取id集合, 以数组形式呈现
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();
로그인 후 복사
7. 구성 요소 클래스가 작업을 트리거하고 상태를 가져옵니다
export const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey)
export const selectTodos = createSelector(selectTodo, selectAll)
로그인 후 복사

8. 구성 요소 템플릿 표시 상태

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

@NgModule({
  imports: [
    StoreRouterConnectingModule.forRoot()
  ]
})
export class AppModule {}
로그인 후 복사
Action Payload

1. Action을 트리거하기 위해 구성 요소에서 디스패치를 ​​사용할 때 매개 변수를 전달하면 매개 변수가 결국 Action 개체에 배치됩니다.

import * as fromRouter from "@ngrx/router-store"

export interface AppState {
  router: fromRouter.RouterReducerState
}
export const reducers: ActionReducerMap<AppState> = {
  router: fromRouter.routerReducer
}
로그인 후 복사
2. Action Creator 기능을 생성할 때 매개변수를 가져오고 매개변수 유형을 지정합니다.
// 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)
로그인 후 복사
// 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)
  }
}
로그인 후 복사
3. Reducer의 Action 객체를 통해 매개변수를 가져옵니다.

rrreeeMetaReducer

metaReducer는 Action -> Reducer 사이의 연결 고리로 개발자가 Action(일반 Reducer 함수가 호출되기 전에 호출됨)을 전처리할 수 있습니다.

rrreee

Effect

요구 사항: 페이지에 버튼을 추가하고 버튼을 클릭한 후 1초 동안 지연하여 값을 높입니다. 1. 컴포넌트 템플릿에 비동기 값 증가를 위한 버튼을 추가합니다. 버튼을 클릭한 후 increment_async 메서드를 실행합니다.rrreee

2. > 메소드에 비동기 작업을 수행하는 Action을 실행합니다

rrreee3. Action 파일rrreee

4에 비동기 작업을 수행하는 Action을 추가하고 Action을 받아 Side Effect를 실행합니다. 계속해서 Action🎜🎜ng g effect store/효과/counter --root --module app.module.ts --skipTests🎜🎜Effect 함수를 트리거하세요. 관련 모듈은 루트 모듈에서 가져와야 합니다. 🎜rrreee🎜🎜Entity🎜🎜🎜🎜🎜1에 따라 다릅니다. 개요🎜🎜🎜🎜Entity는 엔터티로 번역되며 엔터티는 컬렉션의 데이터 조각입니다. 🎜🎜NgRx는 엔터티 어댑터 개체를 제공하며, 그 목적은 개발자가 엔터티를 운영하는 효율성을 높이는 것입니다. 🎜🎜🎜🎜2 🎜🎜🎜https://ngrx.io/guide/entity/adapter#adapter-collection-methods🎜🎜🎜🎜4. Selector🎜🎜🎜rrreeerrreee🎜🎜Router Store🎜🎜🎜🎜🎜1. 🎜 🎜 🎜1) 모듈 소개 🎜rrreee🎜2) 라우팅 상태를 Store🎜rrreee🎜🎜🎜2에 통합하여 라우팅 상태를 얻기 위한 선택기를 만듭니다🎜🎜🎜rrreeerrreee🎜더 많은 프로그래밍 관련 지식을 보려면 🎜프로그래밍 비디오🎜를 방문하세요! ! 🎜

위 내용은 각도 학습 상태 관리자 NgRx에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:csdn.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿