Redux是根據Facebook的flux所產出的一個架構. 簡單介紹請參考這裡
簡單的動作及資料流程如下
複雜一點的流程圖如下
每一個階段都有他應該要做的事情
- Action: 處理資料,呼叫API, 任何有可能產生副作用的行為都在這階段處理, 通常都是回傳JSON object.
- Reducer: 根據Action傳來的動作和資料,來決定與原本的資料(In Store)的關係,例如、新增、更新、移除或過濾等,回傳要顯示在View上面的資料
##程式碼
@Component程式的基本架構
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| import { Component, Inject, ApplicationRef } from 'angular2/core';
import * as TodoAction from '../../actions/ToDo';
@Component({ selector: 'ck-todo-app', template: require('./TodoPage.html') }) export class CkTodoApp { private disconnect: Function; private unsubscribe: Function; private items: any; private task: any;
constructor( @Inject('ngRedux') private ngRedux, private applicationRef: ApplicationRef) { }
ngOnInit() { this.disconnect = this.ngRedux.connect( this.mapStateToThis, this.mapDispatchToThis)(this);
this.unsubscribe = this.ngRedux.subscribe(() => { this.applicationRef.tick(); }); }
ngOnDestroy() { this.unsubscribe(); this.disconnect(); }
mapStateToThis(state) { return { items: state.todo, task: state.newtodo }; } mapDispatchToThis(dispatch) { return { add: (task) => dispatch(TodoAction.add(Object.assign({}, task))), remove: (task) => dispatch(TodoAction.remove(task)) }; } };
|
TodoPage.html
1 2 3 4 5 6 7 8 9 10 11 12
| <div class="clearfix mx-auto col-8"> <h3>TODO App</h3> <div class="clearfix mxn2"> <input type="text" [(ngModel)]="task.content" class="input inline-block" /> <button class="btn btn-primary inline-block" (click)="add(task)">Add</button> </div> <div class="clearfix mxn2"> <ul class="list-reset" *ngFor="#item of items"> <li>{{ item.content }} <span (click)="remove(item)">x</span></li> </ul> </div> </div>
|
###註冊Store as provider in Angular2 application
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import { enableProdMode, provide } from 'angular2/core'; import { bootstrap} from 'angular2/bootstrap'; import { ROUTER_PROVIDERS, APP_BASE_HREF } from 'angular2/router'; import { CkDemoApp } from './containers/main-app';
import configureStore from './store/configure-store'; const provider = require('ng2-redux').provider; const store = configureStore({});
declare let __PRODUCTION__: any;
if (__PRODUCTION__) { enableProdMode(); }
bootstrap(CkDemoApp, [ provider(store), ROUTER_PROVIDERS, provide(APP_BASE_HREF, { useValue: '/' }) ]);
|
store/configureStore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
import {createStore, applyMiddleware, compose} from 'redux'; import {fromJS} from 'immutable'; import ReduxThunk from 'redux-thunk'; import rootReducer from '../reducers'; const persistState = require('redux-localstorage');
function configureStore(initialState) { const store = compose( _getMiddleware() )(createStore)(rootReducer, initialState);
return store; }
function _getMiddleware() { let middleware = [ ReduxThunk ];
if (__DEV__) { middleware = [...middleware]; }
return applyMiddleware(...middleware); }
export default configureStore;
|
設定ACTIONs
actions/Todo
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { TODO_ADD, TODO_REMOVE } from '../constants'; export function add(task) { return { type: TODO_ADD, data: task } }
export function remove(task) { return { type: TODO_REMOVE, data: task } }
|
設定可以使用的Reducers
reducers/index
1 2 3 4 5 6 7 8 9 10 11
| import { combineReducers } from 'redux';
import {todo, newtodo} from './todo';
export default combineReducers({ todo, newtodo });
|
reducers/todo.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| import { fromJS, List } from 'immutable'; import { TODO_ADD, TODO_REMOVE } from '../constants';
const INITIAL_STATE = List<any>();
export function todo(state = INITIAL_STATE, action: any = { type: '' }) { switch (action.type) { case TODO_ADD: return state.push(action.data); case TODO_REMOVE: return state.remove(state.indexOf(action.data)); default: return state; } }
export function newtodo(state = { content: '' }, action: any = { type: '' }) { switch (action.type) { case TODO_ADD: return { content: '' }; default: return state; } }
|
CODE
參考資料:
- Angular 2 — Introduction to Redux
- Angular 2 and Redux
- redux
- ng2-redux
- immutable.js
- work with service