在 Angular 应用中,实现状态管理是非常重要的一项任务。状态管理可以帮助我们更好地组织应用的数据流,使得应用更加可维护和可扩展。在本文中,我们将介绍如何使用 ngrx/store 库来实现状态管理。
ngrx/store 是什么?
ngrx/store 是一个基于 Redux 架构的状态管理库。它提供了一个单一的状态存储,以及一组纯函数来更新这个状态。ngrx/store 还提供了一些工具来帮助我们更好地理解应用中的数据流。
安装 ngrx/store
要在 Angular 应用中使用 ngrx/store,我们需要先安装它。在终端中运行以下命令来安装 ngrx/store:
npm install @ngrx/store --save
创建状态
在使用 ngrx/store 之前,我们需要先定义应用的状态。状态是一个纯 JavaScript 对象,它描述了应用的当前状态。我们可以使用 Angular CLI 来生成一个状态文件:
ng generate store State --root --module app.module.ts
这个命令将在 app 目录下创建一个名为 state.ts
的文件,它包含了一个空的状态对象。我们可以向这个对象中添加我们需要的属性和方法。
定义 Action
在 Redux 中,Action 是一个简单的对象,它描述了应用中发生的事件。Action 通常包含一个类型和一些负载数据。在 ngrx/store 中,我们需要定义所有可能的 Action 类型。我们可以使用 Angular CLI 来生成一个 Action 类型文件:
ng generate action Actions
这个命令将在 app 目录下创建一个名为 actions.ts
的文件,它包含了一个空的 Action 类型对象。我们可以向这个对象中添加我们需要的类型。
创建 Reducer
在 Redux 中,Reducer 是一个纯函数,它接收当前状态和一个 Action,返回一个新的状态。在 ngrx/store 中,我们需要定义一个或多个 Reducer 来处理所有可能的 Action 类型。我们可以使用 Angular CLI 来生成一个 Reducer 文件:
ng generate reducer reducers --module app.module.ts
这个命令将在 app 目录下创建一个名为 reducers.ts
的文件,它包含了一个空的 Reducer 函数。我们可以向这个函数中添加我们需要的状态更新逻辑。
注册 Reducer
在 Angular 中,我们需要将 Reducer 注册到应用的模块中。打开 app.module.ts
文件,将 Reducer 导入并添加到 StoreModule.forRoot()
方法中:
// javascriptcn.com 代码示例 import { reducers } from './reducers'; @NgModule({ imports: [ StoreModule.forRoot(reducers), // ... ], // ... }) export class AppModule { }
现在,我们已经成功地将 ngrx/store 集成到了我们的 Angular 应用中。接下来,我们将展示如何使用 ngrx/store 来实现状态管理。
读取状态
在 ngrx/store 中,我们可以使用 select()
方法来读取状态。这个方法接收一个函数作为参数,这个函数会从整个状态中选择一个子集并返回它。我们可以在组件中使用 select()
方法来读取状态:
// javascriptcn.com 代码示例 import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; interface AppState { count: number; } @Component({ selector: 'app-root', template: ` <p>Count: {{ count$ | async }}</p> <button (click)="increment()">Increment</button> `, }) export class AppComponent { count$: Observable<number>; constructor(private store: Store<AppState>) { this.count$ = store.select(state => state.count); } increment() { this.store.dispatch({ type: 'INCREMENT' }); } }
在上面的代码中,我们使用了 store.select()
方法来读取状态中的 count
属性。我们将这个属性绑定到了模板中,以便在页面上显示它。我们还定义了一个 increment()
方法,它会分发一个 INCREMENT
Action,用于更新状态。
更新状态
在 ngrx/store 中,我们使用 dispatch()
方法来分发一个 Action。Action 会被传递到所有注册了 Reducer 的函数中,每个 Reducer 都可以根据 Action 的类型来更新状态。在组件中,我们可以使用 store.dispatch()
方法来分发一个 Action:
// javascriptcn.com 代码示例 import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; interface AppState { count: number; } @Component({ selector: 'app-root', template: ` <p>Count: {{ count$ | async }}</p> <button (click)="increment()">Increment</button> `, }) export class AppComponent { constructor(private store: Store<AppState>) {} increment() { this.store.dispatch({ type: 'INCREMENT' }); } }
在上面的代码中,我们定义了一个 increment()
方法,它会分发一个 INCREMENT
Action。这个 Action 会被传递到所有注册了 Reducer 的函数中,每个 Reducer 都可以根据 Action 的类型来更新状态。
使用 Effects
在实际应用中,我们可能需要在处理 Action 时执行一些异步操作,比如获取数据或发送请求。在 ngrx/store 中,我们可以使用 Effects 来处理这些异步操作。Effects 是一个独立的模块,它负责监听 Action 并执行一些副作用。我们可以使用 Angular CLI 来生成一个 Effects 文件:
ng generate effect effects --module app.module.ts
这个命令将在 app 目录下创建一个名为 effects.ts
的文件,它包含了一个空的 Effects 类。我们可以向这个类中添加我们需要的副作用逻辑。
在 Effects 中,我们可以使用 Actions
对象来监听 Action。我们可以使用 ofType()
方法来选择需要处理的 Action 类型。在处理 Action 时,我们可以执行一些异步操作,比如发送 HTTP 请求。在处理完异步操作后,我们可以使用 map()
方法来创建一个新的 Action,并将它分发到 Store 中。
// javascriptcn.com 代码示例 import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { map, mergeMap } from 'rxjs/operators'; import { HttpClient } from '@angular/common/http'; @Injectable() export class Effects { loadData$ = createEffect(() => { return this.actions$.pipe( ofType('LOAD_DATA'), mergeMap(() => this.http.get('/api/data').pipe( map(data => ({ type: 'DATA_LOADED', payload: data })) ) ) ); }); constructor(private actions$: Actions, private http: HttpClient) {} }
在上面的代码中,我们定义了一个 loadData$
Effects。它会监听 LOAD_DATA
Action,并执行一个 HTTP GET 请求。在请求完成后,它会创建一个新的 Action DATA_LOADED
,并将它分发到 Store 中。
总结
在本文中,我们介绍了如何使用 ngrx/store 来实现状态管理。我们学习了如何定义状态、Action 和 Reducer,以及如何读取和更新状态。我们还介绍了如何使用 Effects 来处理异步操作。通过使用 ngrx/store,我们可以更好地组织应用的数据流,使得应用更加可维护和可扩展。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65693540d2f5e1655d1c05b4