Angular之store全局状态管理 浅学

        在 Angular 应用中,我们可以使用 @ngrx/store 进行状态管理可以有效地管理和跟踪应用程序的状态变化。@ngrx/store 是基于 Redux 模式的状态管理库,它提供了一种集中式存储管理应用程序状态的方式。以下是关于 @ngrx/store 的详细解释和使用方法:

前言

   @ngrx/store 提供了一种强大的机制来管理 Angular 应用程序的状态,使得应用程序的状态变化变得可预测和可追踪。通过定义 actions、reducers 和 selectors,并使用 select 函数来订阅状态变化,我们可以实现高效的状态管理,同时提高应用程序的可维护性和可测试性。同时,结合 Effects 可以处理复杂的异步逻辑,使得应用程序的状态管理更加完善和健壮。

1. 核心概念

1.1. Store

        Store是整个应用程序状态的单一来源。它是一个 RxJS Observable,用于订阅状态的变化。通过 Store,我们可以获取、更新和订阅应用程序中的状态。

1.2. State

        State 是应用程序的当前状态,通常表示为一个 JavaScript 对象。在 @ngrx/store  中,所有的状态都被组织成一个状态树,每个部分状态(或称为状态片段)都由一个 reducer 函数管理。

1.3. Actions

        Actions 是一个描述状态变化的简单对象,它包含了一个 type属性和可选的playload属性。通过 dispatching actions,我们可以触发状态的变化。

1.4. Reducers

       Reducers是纯函数,它接收当前状态和一个 action,并返回新的状态。Reducers 用于处理不同类型的 actions,更新相应的部分状态。

2. 安装和配置 @ngrx/store

2.1. 安装 @ngrx/store
npm install @ngrx/store --save
2.2. 在 Angular 应用中配置 StoreModule

        在 Angular 的根模块(通常是 AppModule)中导入 StoreModule.forRoot(),并传入一个包含所有 reducers 的对象。

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { reducers, metaReducers } from './reducers'; // 导入应用程序的 reducers@NgModule({imports: [BrowserModule,StoreModule.forRoot(reducers, {metaReducers,runtimeChecks: {strictStateImmutability: true,strictActionImmutability: true,}})],declarations: [],bootstrap: []
})
export class AppModule { }
  • reducers是一个对象,包含了应用程序的所有 reducer 函数。
  • metaReducers是一些处理 reducer 的高阶函数,例如日志记录、状态恢复等。
  • runtimeChecks是一个可选配置对象,用于开启严格的状态和 action 不可变性检查。

3. 创建和使用 Actions、Reducers 和 State

3.1. 定义 Actions
// user.actions.ts
import { createAction, props } from '@ngrx/store';
import { User } from './user.model';export const setUser = createAction('[User] Set User', props<{ user: User }>());export const clearUser = createAction('[User] Clear User');
3.2. 创建 Reducers
// user.reducer.ts
import { Action, createReducer, on } from '@ngrx/store';
import { User } from './user.model';
import * as UserActions from './user.actions';export interface UserState {user: User | null;
}export const initialState: UserState = {user: null,
};const userReducer = createReducer(initialState,on(UserActions.setUser, (state, { user }) => ({ ...state, user })),on(UserActions.clearUser, (state) => ({ ...state, user: null })),
);export function reducer(state: UserState | undefined, action: Action) {return userReducer(state, action);
}
3.3. 使用 State 和 Dispatch Actions
// user.component.ts
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { AppState } from './app.state'; // 应用状态的类型定义
import { setUser, clearUser } from './store/user/user.actions'; // Actions 的导入@Component({selector: 'app-user',templateUrl: './user.component.html',styleUrls: ['./user.component.css']
})
export class UserComponent {constructor(private store: Store<AppState>) { }setUser(): void {const user = { id: '1', name: 'John Doe', email: 'john.doe@example.com' };this.store.dispatch(setUser({ user }));}clearUser(): void {this.store.dispatch(clearUser());}}

4. 在组件中使用 select 函数获取状态

4.1. 定义选择器函数
// user.selector.ts
import { createSelector, createFeatureSelector } from '@ngrx/store';
import { AppState } from '../../app.state'; // 应用状态的类型定义
import { UserState } from './user.reducer'; // 用户状态的类型定义// 创建特性选择器,用于选择用户状态
export const selectUserState = createFeatureSelector<AppState, UserState>('user');// 创建选择器函数,用于选择用户信息
export const getUser = createSelector(selectUserState,(state: UserState) => state.user
);
4.2. 在组件中使用 select 函数订阅状态
// user.component.ts
import { Component, OnInit } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { AppState } from './app.state'; // 应用状态的类型定义
import { Observable } from 'rxjs';
import { getUser } from './store/user/user.selector'; // 选择器函数的导入
import { User } from './store/user/user.model'; // 用户模型的导入@Component({selector: 'app-user',templateUrl: './user.component.html',styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {user$: Observable<User>; // 声明一个可观察对象,用来订阅用户状态constructor(private store: Store<AppState>) { }ngOnInit(): void {this.user$ = this.store.pipe(select(getUser)); // 使用 select 函数选择用户状态}
}
4.3. 在模板中使用 Async 管道订阅状态
<!-- user.component.html -->
<div *ngIf="user$ | async as user"><p>User Name: {{ user.name }}</p><p>User Email: {{ user.email }}</p>
</div>

5. 异步状态管理

        对于异步操作(如 HTTP 请求),可以使用 Effects,它允许我们在响应 action 时执行副作用,并将结果作为新的 action 分发到 store 中。这样可以保持 reducer 函数的纯粹性。

6. forFeature方法

        在 @ngrx/store 中,forFeature 方法是用来在特性模块中注册和配置状态的一种重要方式。特性模块可以理解为应用程序中的一个子模块,它可能包含了相关的业务逻辑、状态管理和视图组件。使用 forFeature 可以使得特性模块中的状态管理更加模块化和独立,同时能够与全局状态进行合理的整合。

使用场景和示例
1. 在特性模块中注册状态

        假设我们有一个应用程序,其中有一个特性模块管理用户信息的状态。我们可以使用 forFeature 来注册并配置该特性模块的状态。

// user.reducer.ts
import { Action, createReducer, on } from '@ngrx/store';
import { User } from './user.model';
import * as UserActions from './user.actions';export interface UserState {user: User | null;
}export const initialState: UserState = {user: null,
};const userReducer = createReducer(initialState,on(UserActions.setUser, (state, { user }) => ({ ...state, user })),on(UserActions.clearUser, (state) => ({ ...state, user: null })),
);export function reducer(state: UserState | undefined, action: Action) {return userReducer(state, action);
}
2. 在特性模块中使用 forFeature

        在特性模块中,我们需要导入 StoreModule 和相应的 reducer 函数,并使用 forFeature 来注册该特性模块的状态。

// user.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { StoreModule } from '@ngrx/store';
import { reducer } from './user.reducer'; // 导入用户特性模块的 reducer@NgModule({declarations: [],imports: [CommonModule,StoreModule.forFeature('user', reducer), // 使用 forFeature 注册用户特性模块的状态],
})
export class UserModule { }
详细解释
  1. Reducer 定义

    user.reducer.ts 中定义了一个用户特性模块的 reducer 函数,它负责管理用户信息的状态变化。这里的 initialState 定义了初始的状态对象,userReducer 使用 createReducer 函数来处理不同类型的 action,并更新相应的状态。

  2. 特性模块中的 StoreModule.forFeature

    UserModule 中,我们使用 StoreModule.forFeature 方法来注册用户特性模块的状态。forFeature 方法接收两个参数:

    • 第一个参数是一个字符串,用来标识注册的状态在全局状态树中的位置。在这里我们使用 user,表示用户特性模块的状态将会存储在全局状态树的 user 键下。
    • 第二个参数是特性模块的 reducer 函数,用来管理特性模块中的状态变化。
  3. 在应用中使用特性模块

    在主模块或其他需要使用用户特性模块的地方,只需导入 UserModule,Angular 就会自动注册和配置该模块的状态。

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { reducers, metaReducers } from './reducers'; // 导入应用程序的 reducers
import { UserModule } from './user/user.module'; // 导入用户特性模块@NgModule({imports: [BrowserModule,StoreModule.forRoot(reducers, { metaReducers }),UserModule, // 导入并使用用户特性模块],declarations: [],bootstrap: []
})
export class AppModule { }
优势和适用场景
  • 模块化:使用 forFeature 可以使得状态管理更加模块化,每个特性模块可以独立管理自己的状态和逻辑,提高了代码的可维护性和可重用性。
  • 分割状态:通过注册不同的特性模块,可以将全局状态树分割为多个小块,使得状态管理更加清晰和灵活。
  • 依赖注入:Angular 的依赖注入机制能够有效地管理特性模块的依赖关系,使得状态的使用和管理更加一致和可控。

参考博文

https://blog.51cto.com/devpoint/4925185

Angular Ngrx 里 Store 和 State 的关系-阿里云开发者社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/49224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MSPM0G3507学习笔记1:开发环境_引脚认识与点灯

今日速通一款Ti的单片机用于电赛&#xff1a;MSPM0G3507 这里默认已经安装好了Keil5_MDK 首先声明一下: 因为是速成&#xff0c;所以需要一定单片机学习基础&#xff0c;然后我写的也不会详细&#xff0c;这个专栏的笔记也就是自己能看懂就行的目标~~~ 文章提供测试代码解…

智能制造·数字化工厂建设规划方案(65P)

获取完整PPT见下图 更多有关华为研发管理/IPD、MBSE、PLM、ERP、MES、数据治理、数字样机等方面免费解决方案、资料获取&#xff0c;请见下图

Ecovadis评估的流程是什么

Ecovadis评估流程是一个全面、系统且注重细节的过程&#xff0c;旨在为企业提供关于其可持续性表现的深入洞察。这一评估不仅覆盖了企业在环境、社会和治理方面的多个方面&#xff0c;还强调了持续改进的重要性&#xff0c;确保企业能够不断提升其CSR&#xff08;企业社会责任&…

ES中聚合查询之date_histogram查询出现key_as_string 和 key含义

ES中聚合查询之date_histogram查询出现key_as_string 和 key含义 DSL语句 #实例 GET /capture_features_202407/_search {"query": {"bool": {"must": [{"terms": {"plateNo": ["汉A00001"]}},{"range&quo…

构建一个具有深色模式的简单React Web应用

在当今的Web开发世界里,创建一个既美观又功能丰富的用户界面是至关重要的。在本文中,我们将探讨如何使用React构建一个简单但功能强大的Web应用,它包含导航栏、内容展示区域和深色模式切换功能。 项目概述 我们的目标是创建一个具有以下特性的Web应用: 左侧导航栏,包含四个链…

Qt创建自定义组件并且promote to之后导致编译错误(CMake)

创建自定组件并且加入到全局(勾选"Global include"选项)后&#xff0c;重新编译&#xff0c;元对象编译器生成的ui_xxxx.h文件中会新加入自定义组件的头文件&#xff1a; 如图所示&#xff0c;编译器提示找不到自定义组件的头文件&#xff1a; Solution: 在CMakeL…

Java开发之LinkedList源码分析

#来自ゾフィー&#xff08;佐菲&#xff09; 1 简介 LinkedList 的底层数据结构是双向链表。可以当作链表、栈、队列、双端队列来使用。有以下特点&#xff1a; 在插入或删除数据时&#xff0c;性能好&#xff1b;允许有 null 值&#xff1b;查询效率不高&#xff1b;线程不安…

opencascade AIS_InteractiveContext源码学习9 obsolete methods

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

Leetcode3216. 交换后字典序最小的字符串

Every day a Leetcode 题目来源&#xff1a;3216. 交换后字典序最小的字符串 解法1&#xff1a;模拟 找到第一个 s[i] > s[i 1]&#xff0c;且它们奇偶性相同&#xff0c;交换它们。 代码&#xff1a; /** lc appleetcode.cn id3216 langcpp** [3216] 交换后字典序最小…

Python群体趋向性潜关联有向无向多图层算法

&#x1f3af;要点 &#x1f3af;算法模型图层节点和边数学定义 | &#x1f3af;算法应用于贝叶斯推理或最大似然优化概率建模的多图层生成模型 | &#x1f3af;算法结合图结构边和节点属性 | &#x1f3af;对比群体关联预测推理生成式期望最大化多图层算法 | &#x1f3af;使…

【故障排除】Unity在编辑器模式下Play时闪退

一开始以为是偶然的情况&#xff0c;但逐渐发现了规律&#xff1a; 每次某个角色释放技能的时候就会闪退。 为了找到问题代码&#xff0c;找了一下存放运行Log的文件夹&#xff1a; 打开 Console 窗口&#xff08;菜单&#xff1a;Window > General > Console&#xff…

[Jenkins]jenkins-cli.jar调用用户token启动任务

背景&#xff1a;项目入了一群od伙伴&#xff0c;但是od伙伴有单独的构建工程需要提交&#xff0c;由于jenkins的版本太拉闸&#xff0c;不能配置根据role和项目分权限&#xff0c;插件安装失败&#xff0c;不得已想到一个办法。让OD伙伴&#xff0c;在本地&#xff0c;用java&…

Mindspore框架循环神经网络RNN模型实现情感分类|(二)词向量

Mindspore框架循环神经网络RNN模型实现情感分类 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;一&#xff09;IMDB影评数据集准备 Mindspore框架循环神经网络RNN模型实现情感分类|&#xff08;二&#xff09;预训练词向量 Mindspore框架循环神经网络RNN模型实现…

keil5中 FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED的问题

用破解软件激活一下cid&#xff1a; 再重新进入keil中&#xff0c;rebuild&#xff1a;

【C++】【继承】【子对象】【构造函数】含子对象的派生类的构造函数写法

&#xff08;1&#xff09;子对象的概念&#xff1a;若派生类A1的数据成员中包含基类A的对象a&#xff0c;则a为派生类A1的子对象 &#xff08;2&#xff09;含子对象的派生类的构造函数的执行顺序是&#xff1a; ①调用基类构造函数&#xff0c;对基类数据成员初始化 ②调用子…

最优雅的PHP框架—laravel

一、介绍 Laravel是一种流行的PHP框架,旨在帮助开发人员构建高质量的Web应用程序。它提供了许多开箱即用的功能和工具,使开发过程更加简单和快速。 以下是一些Laravel的主要特点和功能: 简洁优雅的语法:Laravel采用了简洁、优雅的语法,使得编写代码更加简单和易于理解。…

2025广州国际图文办公耗材展览会

2025广州国际图文办公耗材展览会 时间:2025年4月10-12日 地点:琶洲广州国际采购中心展览馆 主办单位:广州环之球会展服务有限公司 协办单位:广东省现代办公设备协会 广州市办公耗材行业协会 战略伙伴:广州市现代办公设备行业商会 科印传媒 【图文办公打印耗…

K8s-控制器

一 为什么使用控制器 pod控制器 作用&#xff1a;1.pod类型资源删除&#xff0c;不会重建 2.控制器可以帮助用户监控&#xff0c;并保证节点上运行定义好的pod副本数 3.pod超过或低于用户期望&#xff0c;控制器会创建、删除pod副本数量 控制器类型&am…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的马跳棋游戏(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

Ubuntu 22.04安装Visual Studio Code(VS Code)配置C++,Python

目录 1,下载 通过命令行安装 2,配置 2.1 vscode安装C/C 2.1.1 vscode安装运行环境 3,测试 vscode测试 4&#xff0c;配置python 选择解释器Python是一个解释性语言&#xff0c;现在需告知VSCode使用哪个解释器 ctrlshiftp 输入&#xff1a;Python: Select Interprete…