Angular 5+中使用Angular-redux分发Action时如何传递Payload?
Hey there! I totally get the frustration—sometimes official docs skip over these practical, day-to-day details. Let me break down exactly how to pass payloads with your Angular-redux actions, even though the base Action setup only shows a type property.
1. Define Actions with Payload Support
The base "Action" concept in Redux (and by extension Angular-redux) is flexible—you're not limited to just the type property. You can extend it to include a payload by either using interfaces or classes (classes are great for type safety in TypeScript):
Using Interfaces
// Define a base action interface interface BaseAction { type: string; } // Create a generic interface for actions with payloads interface ActionWithPayload<T> extends BaseAction { payload: T; } // Example action types const ADD_ITEM = '[Items] Add Item'; const DELETE_ITEM = '[Items] Delete Item'; // Create type-safe action creators const addItem = (item: Item): ActionWithPayload<Item> => ({ type: ADD_ITEM, payload: item }); const deleteItem = (itemId: number): ActionWithPayload<number> => ({ type: DELETE_ITEM, payload: itemId });
Using Classes (Popular for TypeScript Projects)
Classes make it easier to enforce type consistency and are widely used in Angular-redux setups:
export class AddItemAction { // Declare the action type as a readonly property readonly type = '[Items] Add Item'; // Inject the payload via the constructor constructor(public payload: Item) {} } export class DeleteItemAction { readonly type = '[Items] Delete Item'; constructor(public payload: number) {} }
2. Handle Payloads in Your Reducer
Once your actions include payloads, you can access them directly in your reducer to update the state:
import { AddItemAction, DeleteItemAction } from './item.actions'; import { Item } from './item.model'; type ItemActions = AddItemAction | DeleteItemAction; export function itemsReducer(state: Item[] = [], action: ItemActions): Item[] { switch (action.type) { case '[Items] Add Item': // Use the payload to add a new item to the state return [...state, action.payload]; case '[Items] Delete Item': // Use the payload (item ID) to filter out the item return state.filter(item => item.id !== action.payload); default: return state; } }
3. Dispatch Actions with Payloads
In your components or services, dispatch the action by creating an instance of your action class (or calling your action creator function) and passing the payload directly:
import { Component } from '@angular/core'; import { Store } from '@angular-redux/store'; import { AddItemAction } from './item.actions'; import { Item } from './item.model'; @Component({ selector: 'app-item-form', template: `...` }) export class ItemFormComponent { constructor(private store: Store<any>) {} onSubmit(newItem: Item) { // Dispatch the action with your payload this.store.dispatch(new AddItemAction(newItem)); } }
Quick Note
Angular-redux follows the core Redux pattern, where actions are plain objects (or class instances that compile to plain objects) with a type and optional payload. The official docs might not explicitly cover this because it's a fundamental Redux concept, but extending actions to include payloads is totally standard and encouraged.
内容的提问来源于stack exchange,提问作者user1337

