0.0.13 • Published 8 years ago
@ngfk/ng-store v0.0.13
@ngfk/ng-store
State management powered by RxJS enforcing type safety, inspired by @ngrx/store and Redux. Creating reducers and dispatching actions will be type safe.
Setup
TLDR 1. Define state structure 2. Map actions 3. Create reducers 4. Create store
1. Define state structure
interface Todo {
readonly id: number;
readonly text: string;
readonly completed: boolean;
}
enum Filter {
All,
Completed,
Active
}
interface State {
readonly todos: Todo[];
readonly filter: Filter;
}2. Map actions
interface TodoActionMap {
TODO_ADD: { id: number; text: string };
TODO_TOGGLE: number;
TODO_REMOVE: number;
}
interface FilterActionMap {
FILTER_SET: Filter;
}
interface ActionMap extends TodoActionMap, FilterActionMap {}3. Create reducers
const todosReducer = createReducer<Todo[], TodoActionMap>([], {
TODO_ADD: (state, payload) => [
...state,
{ id: payload.id, text: payload.text, completed: false }
],
TODO_TOGGLE: (state, payload) => {
return state.map(
todo =>
todo.id === payload
? { ...todo, completed: !todo.completed }
: todo
);
},
TODO_REMOVE: (state, payload) => {
return state.filter(todo => todo.id !== payload);
}
});
const filterReducer = createReducer<Filter, FilterActionMap>(Filter.All, {
FILTER_SET: (_, payload) => payload
});
const reducer = combineReducers<State>({
todos: todosReducer,
filter: filterReducer
});4. Create store service & provide it
import { Injectable } from '@angular/core';
import { Store } from '@ngfk/store';
import { ActionMap, reducer, State } from '../state';
@Injectable()
export class StoreService extends Store<State, ActionMap> {
constructor() {
super(reducer);
}
}import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgStoreModule } from '@ngfk/ng-store';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
NgStoreModule.forRoot({
store: StoreService
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}Example Usage
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
@Component({
selector: 'app-root',
template: `
<div>
<button (click)="dispatch()">dispatch</button>
<button (click)="clear()">clear</button>
<hr>
<p>State:</p>
<pre>{{todos$ | async | json}}</pre>
</div>
`
})
export class AppComponent {
public todos$: Observable<Todo[]>;
constructor(private store: StoreService) {
this.todos$ = this.store.select(state => state.todos);
}
public dispatch(): void {
this.store.dispatch('TODO_ADD', 'Dispatched TODO!');
}
public clear(): void {
this.store.reset();
}
}