[AngularJS] Write a simple Redux store in AngularJS app
2016-11-09 17:25
495 查看
The first things we need to do is create a reducer:
It has some default initialize data. What it does is just simply return the state.
Then let's create a gloable store for the app, which has two methods, getState, dispatch. Two props: reducer, state.
Once we got that, we are going to init our store:
We passed in categoreis reudcer and the initialCategories state.
To make it available to Angular APP. we need to make it injectable:
Then we can use it in our app:
Now we are going to simply the code a little bit, we going to make a subscribe method so that we don't need to call getState() method everytime after we dispatch an action.
You can think that the subscribe method is a just callback function which each time we dispatch an action, it will be called. And inside the callback function, we will call this.store.getState() to get the value.
Currently inside the dispatch() metod, we pass in an object with type and payload. It would be better if we can manage those action in a single place. There is where Action creator comes in to play.
To make it avaiable to Angular App, we can create a factory for this:
Then we can use it inside the controller:
/** * CONSTANT * @type {string} */ export const GET_CATEGORIES = "GET_CATEGORIES"; /** * INIT VALUE */ export const initialCategories = [ {id: 0, name: 'Development'}, {id: 1, name: 'Design'}, {id: 2, name: 'Exercise'}, {id: 3, name: 'Humor'} ]; /** * REDUCERS * @type {string} */ export const categories = (state = initialCategories, {type, payload}) => { switch(type) { case GET_CATEGORIES: return payload || state; default: return state; } };
It has some default initialize data. What it does is just simply return the state.
Then let's create a gloable store for the app, which has two methods, getState, dispatch. Two props: reducer, state.
class Store { constructor(reducer, initialState) { this.reducer = reducer; this.state= initialState; } getState() { return this.state } dispatch() { this.state = this.reducer(this.state, action); } }
Once we got that, we are going to init our store:
import {categories, initialCategories} from './components/categories/category.state'; import Store from './app.store'; const store = new Store(categories, initialCategories);
We passed in categoreis reudcer and the initialCategories state.
To make it available to Angular APP. we need to make it injectable:
let appModule = angular.module('app', [ CommonModule.name, ComponentsModule.name ]) .value('store', store)
Then we can use it in our app:
class CategoriesController { constructor(store) { 'ngInject'; angular.extend(this, { store }); } $onInit() { this.store.dispatch({type: GET_CATEGORIES}); this.categories = this.store.getState(); } }
Now we are going to simply the code a little bit, we going to make a subscribe method so that we don't need to call getState() method everytime after we dispatch an action.
You can think that the subscribe method is a just callback function which each time we dispatch an action, it will be called. And inside the callback function, we will call this.store.getState() to get the value.
class Store { constructor(reducer, initialState) { this.reducer = reducer; this.state = initialState; this.listeners = []; } getState() { return this.state; } dispatch(action) { this.state = this.reducer(this.state, action); this.listeners.forEach((l) => l()); } subscribe(listener) { this.listeners = [ ...this.listeners, listener ]; // return an unsubscribe function return () => { this.listeners = this.listeners.filter(l => l !== listener); } } } export default Store;
class CategoriesController { constructor($timeout, store) { 'ngInject'; angular.extend(this, { $timeout, store }); } $onInit() { this.unsubscribe = this.store.subscribe(() => { this.categories = this.store.getState(); }); this.store.dispatch({type: GET_CATEGORIES}); } }
Currently inside the dispatch() metod, we pass in an object with type and payload. It would be better if we can manage those action in a single place. There is where Action creator comes in to play.
/** * ACTIONS CREATOR */ export const CategoriesActions = () => { const getCategoreis = (categories) => { return {type: GET_CATEGORIES, payload: categories} }; const getCurrentCategory = (currentCategory) => { return {type: GET_CURRENT_CATEGORY, payload: currentCategory} }; return { getCategoreis, getCurrentCategory }; };
To make it avaiable to Angular App, we can create a factory for this:
let appModule = angular.module('app', [ CommonModule.name, ComponentsModule.name ]) .value('store', store)
.factory('CategoriesActions', CategoriesActions)
.component('app', AppComponent)
Then we can use it inside the controller:
constructor($timeout, store, CategoriesActions) { 'ngInject'; angular.extend(this, { $timeout, store, CategoriesActions }); }
$onInit() { this.unsubscribe = this.store.subscribe(() => { this.categories = this.store.getState(); }); this.store.dispatch(this.CategoriesActions.getCategoreis()); }
onCategorySelected(currentCategory) { this.currentCategory = category(this.currentCategory, this.CategoriesActions.getCurrentCategory(currentCategory)); }
相关文章推荐
- [AngularJS - app] AngularJS Location-picker app
- 转载:Think in AngularJS:对比jQuery和AngularJS的不同思维模式(大漠穷秋)
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- Confirmation on Leaving the Current Page in an Angular.js App
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- [AngularJS] 5 simple ways to speed up your AngularJS application
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- AngularJS Front-End App with Cloud Storage Tutorial Part 1: Building a Minimal App in Seven Steps
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- [AngularJS] Transforming raw JSON data to meaningful output in AngularJS
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- [AngularJS] Enable Animations Explicitly For A Performance Boost In AngularJS
- AngularJS' Internals In Depth(深入理解 AngularJS)
- Think in AngularJS:对比jQuery和AngularJS的不同思维模式
- ASP.NET Web API 2 external logins with Facebook and Google in AngularJS app
- angularJS开发指南(angularJS developer guide) 之二
- Store Kit Guide(In App Purchase)翻译
- How To Write A Simple PHP/MySQL Web Service for an iOS App(2)