1. 什么是NgRx?
NgRx是Angular状态管理的重要解决方案。它是一个RxJS中心的状态管理库,使用可预测的状态容器,帮助开发人员轻松管理复杂的应用程序状态。
简而言之,NgRx帮助我们更好地管理Angular应用程序中的状态。它提供了一个类似于Redux的状态容器,可以存储和管理应用程序的状态。通过使用NgRx,我们可以在不同的组件之间共享状态,使得我们的状态管理更加集中化和可维护。
2. NgRx的优点
NgRx的最大优点就是它提供了一种可预测的状态容器管理方法。由于Angular通过使用单向数据流模型来管理组件之间的数据传递,因此我们可以更好地控制和维护应用程序的状态。
2.1 可预测性
使用NgRx状态管理,可以确保我们的应用程序状态只能以合适的方式进行更改。所有对应用程序状态的变化都必须通过NgRx状态管理器进行,这样就可以保证应用程序可以以可预测的方式进行交互。
2.2 更容易测试
NgRx的状态容器将所有状态集中保存在一个位置,并将向其他部分提供与状态有关的action和selector方法。这使得我们的单元测试更容易编写,因为我们可以快速定位并测试应用程序的有无状态变化,同时也可以在状态变化之后测试应用程序的行为。
2.3 可扩展性
NgRx的状态管理中心非常适用于大型应用程序。由于状态管理器是可扩展的,并且所有状态都集中在同一个位置,因此我们可以轻松地向应用程序添加新功能或模块,并保持对应用程序状态的控制。
3. NgRx中的核心概念
NgRx实际上是由五个不同的库组成的,每个库都专注于应用程序状态的不同方面。我们来了解一下其中的核心概念。
3.1 Action
Action是一个简单的JavaScript对象,它描述了对应用程序状态的变化。Action包含一个必需的type属性,它是一个字符串,用于描述Action的类型。其他属性可以用来传递Action相关的任何数据。例如,对于一个教案应用程序,我们的Action可能是这样的:
{
type: 'ADD_LESSON',
lesson: {
title: 'A Lesson',
teacher: 'Bob'
}
}
3.2 Reducer
Reducer是一个纯函数,它接受一个当前状态和一个Action对象,并返回新的应用程序状态。Reducer对应用程序状态的任何更改都是通过Action对象实现的。例如,我们的应用程序中可能有一个Reducer函数来处理ADD_LESSON操作:
function lessonReducer(state, action) {
switch (action.type) {
case 'ADD_LESSON':
return {
...state,
lessons: [...state.lessons, action.lesson]
};
default:
return state;
}
}
3.3 Store
Store 是NgRx的核心,它存储您应用程序的状态。要创建一个使用Store的NgRx状态管理器,你需要:
创建一个应用程序状态对象。
创建一个或多个Reducer函数,以处理对状态的操作。
使用createStore()函数创建一个新的存储对象。
创建Store后,我们可以使用它的方法访问应用程序状态,同时也可以派发Action以更改状态。例如,我们可能有以下代码来创建我们的Store:
import { createStore } from '@ngrx/store';
import { lessonReducer } from './reducers/lesson.reducer';
const initialState = {
lessons: []
};
export const store = createStore(lessonReducer, initialState);
3.4 Effects
Effect是一个负责处理异步操作的单独的函数。例如,如果我们的应用程序需要从服务器获取数据,我们可能需要编写一个Effect函数来处理这个数据请求。Effect函数可以使用RxJS Observables和纯函数来处理数据请求,并在完成数据请求后派发Action来更改应用程序状态。
3.5 Selector
Selector是一个纯函数,用于从应用程序状态中选择数据。我们可以将Selector视为一个只读API,它可以通过选择有关应用程序状态的值来提供应用程序的另一层抽象。例如,如果我们的应用程序需要显示所有课程的总数,我们可以编写一个Selector函数来计算这个值:
const lessonSelector = state => state.lesson;
export const lessonCountSelector = createSelector(
lessonSelector,
lesson => lesson.length
);
4. NgRx的基本使用
NgRx的基本使用包括为您的应用程序创建一个Store,编写一个或多个Reducer函数和一个或多个Action,以更改应用程序状态。我们来看一下NgRx在实战中的使用。
4.1 安装NgRx(Version 11.x)
在Angular项目中使用NgRx,我们需要安装以下5个核心包:
npm install --save @ngrx/store @ngrx/effects @ngrx/entity @ngrx/store-devtools @ngrx/router-store
安装这些包后,我们还需要在我们的根模块中导入StoreModule和EffectsModule模块,并将其添加到我们的@NgModule设置中:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot({}),
EffectsModule.forRoot([])
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
4.2 建立你的第一个Reducer函数
在本例中,我们将创建一个reducer函数来管理我们课程的状态。我们将使用一个actions对象来定义我们需要处理的Action对象类型:
import { createAction, createReducer, on } from '@ngrx/store';
export const addLesson = createAction('[Lesson] Add Lesson');
export interface LessonState {
lessons: string[];
}
export const initialState: LessonState = {
lessons: []
};
export const lessonReducer = createReducer(
initialState,
on(addLesson, (state, { lesson }) => ({
...state,
lessons: [...state.lessons, lesson]
}))
);
4.3 在组件中使用状态
接下来,我们可以使用Store提供的许多方法在我们的组件中获取和更改应用程序状态。我们来看一下在组件中如何使用状态:
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { addLesson } from './reducers/lesson.reducer';
@Component({
selector: 'app-root',
template: `
type="text"
class="form-control"
id="lesson-name"
[(ngModel)]="newLesson"
/>
{{ lesson }}
`,
})
export class AppComponent {
newLesson = '';
lessons$ = this.store.select((state) => state.lesson.lessons);
constructor(private store: Store) {}
addLesson() {
this.store.dispatch(addLesson({ lesson: this.newLesson }));
this.newLesson = '';
}
}
4.4 添加DevTools支持
最后,我们可以为我们的应用程序添加Redux DevTools支持,以便我们可以可视化地调试并掌握我们的应用程序状态。我们可以通过将@ngrx/store-devtools包导入我们的根模块并调用instrument()方法来实现此目的:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { lessonReducer } from './reducers/lesson.reducer';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot({ lesson: lessonReducer }),
EffectsModule.forRoot([]),
StoreDevtoolsModule.instrument()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
5. 结语
NgRx是一个非常强大的Angular状态管理库,可以帮助我们轻松地管理复杂的应用程序状态。它提供了可预测的状态容器,并将所有应用程序状态集中在一个位置,使得我们可以更好地控制和维护我们的应用程序状态。同时,我们在实际开发中也可以借助NgRx提供的强大功能,更快地开发出更加稳健的应用程序代码。