npm install @ngrx/core @ngrx/store --save
├─app/
├─state/
│ ├─todo-list/
│ │ ├─todo-list.[actions|reducer|state].ts
export interface State {
todos: Array<Todo>;
};
export interface Todo {
name: string;
done: boolean;
};
export const intitialState: State = {
todos: [
{ name: 'clean room', done: false },
{ name: 'make pancakes', done: false },
{ name: 'spend 3 hours on reddit', done: true }
]
};
import { Action } from '@ngrx/store';
export const TodoListActionTypes = {
ADD_TODO: '[TODO-LIST] ADD_TODO',
TOGGLE_TODO: '[TODO-LIST] TOGGLE_TODO',
};
export const TodoListActions = {
AddTodoAction: class implements Action {
readonly type = TodoListActionTypes.ADD_TODO;
constructor(public payload: {name: string}) { }
},
ToggleTodoAction: class implements Action {
readonly type = TodoListActionTypes.TOGGLE_TODO;
constructor(public payload: {name: string, done?: boolean}) { }
},
};
import { ActionReducer, Action } from '@ngrx/store';
import { State, intitialState } from './todo-list.state';
import { TodoListActionTypes } from './todo-list.actions';
export function todoListReducer(state = intitialState, action: Action) {
switch (action.type) {
case TodoListActionTypes.ADD_TODO: {
const newstate = Object.assign({}, state);
newstate.todos = [
...newstate.todos,
{
name: action.payload.name,
done: false,
}
];
return newstate;
}
case TodoListActionTypes.TOGGLE_TODO: {
const newstate = Object.assign({}, state);
const index = newstate.todos.findIndex(todo => todo.name === action.payload.name);
newstate.todos[index].done = !newstate.todos[index].done;
return newstate;
}
default: {
return state;
}
}
}
(...)
import { StoreModule } from '@ngrx/store';
(...)
import { todoListReducer } from './../state/todo-list/todo-list.reducer';
@NgModule({
(...)
imports: [
(...)
StoreModule.provideStore({
todoListStore: todoListReducer
}),
Add/replace the following:
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Rx';
import { TodoListActions } from '../../state/todo-list/todo-list.actions';
import { State } from '../../state/todo-list/todo-list.state';
(...)
export class TodoListComponent implements OnInit {
list$: Observable<boolean>;
constructor(private store: Store<State>) {
this.list$ = this.store.select('todoListStore');
}
(...)
addTask(name: string) {
this.store.dispatch(
new TodoListActions.AddTodoAction ({ name })
);
}
Replace the *ngfor with
*ngFor="let task of (list$ | async).todos"
import { Store } from '@ngrx/store';
import { TodoListActions } from '../../../state/todo-list/todo-list.actions';
import { State } from '../../../state/todo-list/todo-list.state';
(...)
constructor(private store: Store<State>) { }
(...)
toggleTodo(name: string) {
this.store.dispatch(
new TodoListActions.ToggleTodoAction ({ name })
);
}
Replace [(ngModel)]
with [ngModel]