使用 Angular 2 构建 Redux 应用程序 - 第 1 部分

发布日期:2026-07-12 03:59:03   来源 : 杭州电子商务研究院    浏览量 :5
杭州电子商务研究院 发布日期:2026-07-12 03:59:03  
5

介绍

状态管理一直是前端框架中一个持续存在的问题。前端框架的关键原则是多层次的状态变异,这使得标准 MVC(模型-视图-控制器)方法无效。这种多层状态变异在 Angular 1 中很明显,其中管理应用程序状态的逻辑分布在指令、控制器和服务之间,每个级别都有自己的状态变异逻辑。分段的应用程序状态很容易导致不一致,并且难以测试。

随着前端应用程序变得越来越复杂,对用户输入的反应也越来越强烈,这些问题也变得越来越明显,越来越难以规避。然而,前端开发越来越流行的特点(例如强调函数式编程)催生了一种名为Redux的新型状态管理模型。Redux 将状态集中到一个实体中,让开发人员可以在应用程序的任何位置访问最新状态。

尽管 Redux 是由 React 社区发起的,但ngrx/store等第三方库和rxJS等扩展使得 Redux 成为同样适合在 Angular 2 应用程序中使用的概念。

在本指南中,我将介绍 Redux 的核心概念以及它们如何促进 Angular 2 应用程序。

Redux 的主要概念

Redux 包含三个主要部分

  1. 总店
  2. Reducers
  3. 操作

每个部分在应用程序状态的变异中都扮演着不同的角色。用于处理异步请求(如 API 调用)的中间件将在第二部分中介绍。

主店

存储将整个应用程序状态组合成一个实体,充当Web 应用程序的数据库。存储分为不同的状态,代表应用程序中不同类型的数据。状态是不可变的,但可以通过明确定义的操作进行更改。因此,状态变异受到限制和集中,简化了调试过程并使代码更易于理解。

Reducers

如果 store 是应用程序的数据库,那么 Reducer 就是表。Reducer表示应用程序中以特定方式组成的切片或结构。Reducer 是一个纯函数,它定义在分派操作时状态的切片将如何变化。它接受两个参数,即先前的状态和操作,并返回新状态。

      export interface Reducer<T> {
  (state: T, action: Action): T;
}
    

例子

      export const itemsReducer: ActionReducer<number> = (state = [], action: Action) => {
  switch (action.type) {
    case ADD_ITEM: //adding an item
      const item:Item = action.payload;
      //KEEPING THE STATE IMMUTABLE:
      // We don't perform actions that alter the state such as
      // array.push, array.shift and so on.
      // Instead, we concatenate the item, preserving the state.
      return [ ...state, item ];
    }

    case REMOVE_ITEM://removing the item
    // Again, we don't remove the item, we just filter the new state so
    // that it won't contain the item we're removing
      return state.filter(item => {
        return item.id !== action.payload.id;
      });
    }
}
    

操作

操作表示从应用程序发送到存储的信息的有效负载,通常由用户交互触发。每个 Reducer 都有一组操作类型,用于定义应如何更改状态。操作由类型和有效负载组成:

      export interface Action {
 type: string;
 payload?: any;
}
    

例子

      //making an action for adding an item
dispatch({type: ADD_ITEM, payload: {id: 1, name: 'An item' , category: 'miscellaneous'}})
    

概述

当一个动作被分派时,reducer 会接受它并根据动作类型应用有效负载,然后输出新状态。

存储包含整个状态,reducer 返回状态片段,而操作是预定义的、用户触发的事件,用于传达状态的给定片段应如何更改。如果操作需要异步请求,则使用中间件。reducer 获取其先前的状态,对其应用新操作,然后将其返回。

投影数据

正如您所知,Store 是一个表示应用程序状态的树状结构,由表示状态不同部分的 Reducer 组成。在 Angular 2 的ngrx/store中,store 是一个可观察对象,因此可以响应式地访问应用程序的状态。可观察的 store 还允许我们使用 RxJS 的运算符混合多个状态的值。

      //getting a single slice of the state
store.select('items')

//combining multiple slices
Observable.combineLatest(
  store.select('items'),
  store.select('categories'),
  (items, categories) => {

})
    

Redux 实践

现在您已经了解了主要概念,您可能想知道它们如何在 Angular 2 应用程序中结合在一起。为了说明 Redux 的工作原理,我们将构建一个简单的财务会计工具,该工具将使用 Redux 架构跟踪您的交易。它将具有从虚拟账户中增加或扣除资金的操作。稍后,我们将添加一种查看您当前余额和一些其他统计数据的方法。

设置

我们将使用angular-cli来设置项目:

      ng new financials_app
 cd financials_app
    

ngrx/store是专为 Angular 2 应用程序构建的状态容器。它将为 Redux 架构提供实用程序和构建块。

      npm install @ngrx/core @ngrx/store --save
    

或者,您还可以安装Bootstrap以使应用程序看起来美观且结构良好:

      npm install bootstrap@next
    

将以下行添加到angular-cli.json

app.scripts数组中,作为对象属性:

      "scripts": [
  "../node_modules/jquery/dist/jquery.js",
  "../node_modules/tether/dist/js/tether.js",
  "../node_modules/bootstrap/dist/js/bootstrap.js"
],
    

app.styles数组中:

      "styles": [
  "../node_modules/bootstrap/dist/css/bootstrap.css",
  "styles.css"
]
    

你的第一个 Reducer

在 Redux 应用程序中要做的第一件事是定义您的商店并开始将 Reducer 附加到它。对于应用程序的第一次迭代,我们将添加财务运营的状态。

在您的 Angular 2 应用中,创建一个新目录,其中将包含您的应用程序的 Reducer:

      cd src/app
  mkdir common
    

首先我们来做一个财务运作的模型:

      //src/app/common/operation.model.ts
export class Operation {
  id: number;
  amount: number;
  reason: string;

  constructor() {}
}
    

定义 Reducer 函数

接下来,创建一个文件,其中包含财务操作的操作和简化器的定义:

      //src/app/common/operations.ts
import {ActionReducer, Action, State} from '@ngrx/store';
import {Operation} from "./operation.model";


//definitions of the actions that alter the state
export const ADD_OPERATION = 'Add an operation';
export const REMOVE_OPERATION = 'Remove an operation';
export const INCREMENT_OPERATION = 'Increment an operation';
export const DECREMENT_OPERATION = 'Decrement an operation';


//the initial state of the operations
const initialState:State = [];

//the operationsReducer function: a pure function that is responsible for maintaining the
//financial operations state of your store
export const operationsReducer: ActionReducer = (state = initialState, action: Action) => {
  switch (action.type) {
   //In Redux, you cannot mutate the state. In this case using .push(), .pop(),
   // .shift() or .unshift() is against the convention.
    case ADD_OPERATION: //Action type
      const operation:Operation = action.payload;//the contents of an operation
      return [ ...state, operation ];

    case INCREMENT_OPERATION:
      const operation = ++action.payload.amount;
      return state.map(item => {
        return item.id === action.payload.id ? Object.assign({}, item, op
以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据