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 EffectscreateReducer(MyStoreClass)
: Reducer bootstrap function@Select('my.prop')
: Select decoratorInspired by redux-act and redux-actions for Redux.
See changelog for latest changes.
NOTE: I recommend checking out my latest library called NGXS.
This is sugar to help reduce boilerplate when using Redux patterns. That said, here's the high level of what it provides:
Its dead simple (<100LOC) and you can pick and choose where you want to use it.
To get started, lets install the package thru npm:
npm i ngrx-actions --S
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 {}
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.
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.
一、创建工程,搭建基本结构 计划: 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