当前位置: 首页 > 软件库 > Web应用开发 > Web框架 >

ngrx-actions

⚡️ Actions and Reducer Utilities for NGRX
授权协议 MIT License
开发语言 JavaScript
所属分类 Web应用开发、 Web框架
软件类型 开源软件
地区 不详
投 递 者 傅博容
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

NGRX Actions

Actions/reducer utility for NGRX. It provides a handful of functions to make NGRX/Redux more Angular-tastic.

  • @Store(MyInitialState): Decorator for default state of a store.
  • @Action(...MyActionClass: Action[]): Decorator for a action function.
  • @Effect(...MyActionClass: Action[]): Decorator for a effect function.
  • ofAction(MyActionClass): Lettable operator for NGRX Effects
  • createReducer(MyStoreClass): Reducer bootstrap function
  • @Select('my.prop'): Select decorator

Inspired by redux-act and redux-actions for Redux.

See changelog for latest changes.

NOTE: I recommend checking out my latest library called NGXS.

Whats this for?

This is sugar to help reduce boilerplate when using Redux patterns. That said, here's the high level of what it provides:

  • Reducers become classes so its more logical organization
  • Automatically creates new instances so you don't have to handle spreads everywhere
  • Enables better type checking inside your actions
  • Reduces having to pass type constants by using type checking

Its dead simple (<100LOC) and you can pick and choose where you want to use it.

Getting Started

To get started, lets install the package thru npm:

npm i ngrx-actions --S

Reducers

Next, create an action just like you do with NGRX today:

export class MyAction {
  readonly type = 'My Action';
  constructor(public payload: MyObj) {}
}

then you create a class and decorate it with a Store decorator that containsthe initial state for your reducer. Within that class you define methodsdecorated with the Action decorator with an argument of the action classyou want to match it on.

import { Store, Action } from 'ngrx-actions';

@Store({
    collection: [],
    selections: [],
    loading: false
})
export class MyStore {
    @Action(Load, Refresh)
    load(state: MyState, action: Load) {
        state.loading = true;
    }

    @Action(LoadSuccess)
    loadSuccess(state: MyState, action: LoadSuccess) {
        state.collection = [...action.payload];
    }

    @Action(Selection)
    selection(state: MyState, action: Selection) {
        state.selections = [...action.payload];
    }

    @Action(DeleteSuccess)
    deleteSuccess(state: MyState, action: DeleteSuccess) {
        const idx = state.collection.findIndex(r => r.myId === action.payload);
        if (idx === -1) {
          return state;
        }
        const collection = [...state.collection];
        collection.splice(idx, 1);
        return { ...state, collection };
    }
}

You may notice, I don't return the state. Thats because if it doesn't seea state returned from the action it inspects whether the state was anobject or array and automatically creates a new instance for you. If you aremutating deeply nested properties, you still need to deal with those yourself.

You can still return the state yourself and it won't mess with it. This is helpfulfor if the state didn't change or you have some complex logic going on. This can beseen in the deleteSuccess action.

Above you may notice, the first action has multiple action classes. Thats becausethe @Action decorator can accept single or multiple actions.

To hook it up to NGRX, all you have to do is call the createReducer function passingyour store. Now pass the myReducer just like you would a function with a switch statement inside.

import { createReducer } from 'ngrx-actions';
export function myReducer(state, action) { return createReducer(MyStore)(state, action); }

In the above example, I return a function that returns my createReducer. This is because AoTcomplains stating Function expressions are not supported in decorators if we just assignthe createReducer method directly. This is a known issue and other NGRX things suffer from it too.

Next, pass that to your NGRX module just like normal:

@NgModule({
   imports: [
      StoreModule.forRoot({
         pizza: pizzaReducer
      })
   ]
})
export class AppModule {}

Optionally you can also provide your store directly to the NgrxActionsModule and it will handlecreating the reducer for you and also enables the ability to use DI with your stores. So rather thandescribing in forRoot or forFeature with StoreModule, we call them on NgrxActionsModule.

@NgModule({
   imports: [
      NgrxActionsModule.forRoot({
         pizza: PizzaStore
      })
   ],
   providers: [PizzaStore]
})
export class AppModule {}

Effects

If you want to use NGRX effects, I've created a lettable operator that will allow you topass the action class as the argument like this:

import { ofAction } from 'ngrx-actions';

@Injectable()
export class MyEffects {
    constructor(
        private update$: Actions,
        private myService: MyService
    ) {}

    @Effect()
    Load$ = this.update$.pipe(
        ofAction(Load),
        switchMap(() => this.myService.getAll()),
        map(res => new LoadSuccess(res))
    );
}

In 3.x, we introduced a new decorator called @Effect that you can define in your storeto perform async operations.

@Store({ delievered: false })
export class PizzaStore {
    constructor(private pizzaService: PizzaService) {}

    @Action(DeliverPizza)
    deliverPizza(state) {
        state.delivered = false;
    }

    @Effect(DeliverPizza)
    deliverPizzaToCustomer(state, { payload }: DeliverPizza) {
        this.pizzaService.deliver(payload);
    }
}

Effects are always run after actions.

Selects

We didn't leave out selectors, there is a Select decorator that accepts a (deep) path string. This looks like:

@Component({ ... })
export class MyComponent {
    // Functions
    @Select((state) => state.color) color$: Observable<string>;

    // Array of props
    @Select(['my', 'prop', 'color']) color$: Observable<strinv>;

    // Deeply nested properties
    @Select('my.prop.color') color$: Observable<string>;

    // Implied by the name of the member
    @Select() color: Observable<string>;

    // Remap the slice to a new object
    @Select(state => state.map(f => 'blue')) color$: Observable<string>;
}

This can help clean up your store selects. To hook it up, in the AppModule you do:

import { NgrxActionsModule } from 'ngrx-actions';

@NgModule({
    imports: [NgrxActionsModule]
})
export class AppModule {}

And you can start using it in any component. It also works with feature stores too. Note: The Select decorator has a limitation of lack of type checking due to TypeScript#4881.

Common Questions

  • What about composition? Well since it creates a normal reducer function, you can still use all the same composition fns you already use.
  • Will this work with normal Redux? While its designed for Angular and NGRX it would work perfectly fine for normal Redux. If that gets requested, I'll be happy to add better support too.
  • Do I have to rewrite my entire app to use this? No, you can use this in combination with the tranditional switch statements or whatever you are currently doing.
  • Does it support AoT? Yes but see above example for details on implementation.
  • Does this work with NGRX Dev Tools? Yes, it does.
  • How does it work with testing? Everything should work the same way but don't forget if you use the selector tool to include that in your test runner though.

Community

  • 一、创建工程,搭建基本结构 计划: 1、创建一个angular模版的运用程序 2、引用bootstrap 3、引用@ngrx 1、创建工程 ng new pet-tags-ngrx 2、进入工程文件夹 cd pet-tags-ngrx 3、加入bootstrap npm install bootstrap --save 4、angular.json 引入bootstrap样式 "architect

  •   @ngrx/effect  前面我们提到,在 Book 的 reducer 中,并没有 Search 这个 Action 的处理,由于它需要发出一个异步的请求,等到请求返回前端,我们需要根据返回的结果来操作 store。所以,真正操作 store 的应该是 Search_Complete 这个 Action。我们在 recducer 已经看到了。 对于 Search 来说,我们需要见到这个 A

  • 上一篇:ngRx 官方示例分析 - 2. Action 管理 这里我们讨论 reducer. 如果你注意的话,会看到在不同的 Action 定义文件中,导出的 Action 类型名称都是 Actions ,在导入的时候,同时导入同名的类型就是问题了。这里首先使用了 import as 语法进行重命名。 import * as book from '../actions/book'; import

 相关资料
  • ngrx Style Guide Purpose The idea for this styleguide is to present commonly used techniques for working with ngrx suite and serve as a kind of a cookbook/recipes with a problem/solution theme. The pu

  • What is Ngrx?

  • Angular ngrx-data This repository is now merged with @ngrx into @ngrx/data. You can find the ngrx/data docs here and the github repository with ngrx/data in it here Please read the note above Zero Ngr

  • 下面的表格列了 Spark 支持的一些常用 actions。详细内容请参阅 RDD API 文档(Scala, Java, Python) 和 PairRDDFunctions 文档(Scala, Java)。 Action Meaning reduce(func) Aggregate the elements of the dataset using a function func (which

  • {{action}}帮助程序类用于使HTML元素可单击,并在用户单击事件时将操作转发到应用程序。 语法 (Syntax) <button {{action 'action-name'}}>Click</button> 上面的代码添加了按钮Click到您的应用程序,当用户单击按钮时,操作将转发到指定的操作方法。 下表列出了操作的操作事件及其描述 - S.No. 动作事件和描述 1 动作参数 可以在

  • This repository is no longer maintained, please refer to https://github.com/avatsaev/angular-contacts-app-example Angular Ngrx Socket.IO Example This Angular project demonstrates the implementation of