- Notifications
You must be signed in to change notification settings - Fork175
angular-redux/ng-redux
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Angular bindings forRedux.
For Angular 2+ seeangular-redux/store -- made by the same people that startedng-redux.
ngRedux lets you easily connect your angular components with Redux.
- Installation
- Quick Start
- API
- Dependency Injectable Middleware
- Routers
- Config
- Using DevTools
- Additional Resources
npminstall--saveng-redux
Warning! Starting with 4.0.0, we will no longer be publishing new releases on Bower. You can continue using Bower for old releases, or point your bower config to the UMD build hosted on unpkg that mirrors our npm releases.
{"dependencies": {"ng-redux":"https://unpkg.com/ng-redux/umd/ng-redux.min.js" }}Add the following script tag to your html:
<scriptsrc="bower_components/ng-redux/dist/ng-redux.js"></script>
Or directly from unpkg
<scriptsrc="https://unpkg.com/ng-redux/umd/ng-redux.min.js"></script>
There are three ways to instantiate ngRedux:
You can either pass a function or an object tocreateStoreWith.
With a function:
importreducersfrom'./reducers';import{combineReducers}from'redux';importloggingMiddlewarefrom'./loggingMiddleware';importngReduxfrom'ng-redux';angular.module('app',[ngRedux]).config(($ngReduxProvider)=>{letreducer=combineReducers(reducers);$ngReduxProvider.createStoreWith(reducer,['promiseMiddleware',loggingMiddleware]);});
With an object:
importreducersfrom'./reducers';importloggingMiddlewarefrom'./loggingMiddleware';importngReduxfrom'ng-redux';importreducer3from'./reducer3';angular.module('app',[ngRedux]).config(($ngReduxProvider)=>{reducer3=function(state,action){}$ngReduxProvider.createStoreWith({reducer1:"reducer1",reducer2:function(state,action){},reducer3:reducer3},['promiseMiddleware',loggingMiddleware]);});
In this examplereducer1 will be resolved using angular's DI after the config phase.
You can pass an already existing store to ngRedux usingprovideStore:
importreducersfrom'./reducers';import{createStore,combineReducers}from'redux';importngReduxfrom'ng-redux';constreducer=combineReducers(reducers);conststore=createStore(reducer);angular.module('app',[ngRedux]).config(($ngReduxProvider)=>{$ngReduxProvider.provideStore(store);});
createStore allows you take full control over the store creation. This is handyif you want to control the order of enhancers by your self. It takes a functionthat gets middlewares and enhancers from ngRedux as a parameters. Note thatmiddlewares provided by ngRedux needs to be last ones.
importreducersfrom'./reducers';import{createStore,combineReducers}from'redux';importthunkfrom'redux-thunk';importngReduxfrom'ng-redux';constreducer=combineReducers(reducers);angular.module('app',[ngRedux]).config(($ngReduxProvider)=>{$ngReduxProvider.createStore((middlewares,enhancers)=>{returncreateStore(reducer,{},compose(applyMiddleware(thunk, ...middlewares), ...enhancers))});});
Using controllerAs syntax
import*asCounterActionsfrom'../actions/counter';classCounterController{constructor($ngRedux,$scope){/* ngRedux will merge the requested state's slice and actions onto this, you don't need to redefine them in your controller */letunsubscribe=$ngRedux.connect(this.mapStateToThis,CounterActions)(this);$scope.$on('$destroy',unsubscribe);}// Which part of the Redux global state does our component want to receive?mapStateToThis(state){return{value:state.counter};}}
<div><p>Clicked: {{counter.value}} times</p><buttonng-click='counter.increment()'>+</button><buttonng-click='counter.decrement()'>-</button><buttonng-click='counter.incrementIfOdd()'>Increment if odd</button><buttonng-click='counter.incrementAsync()'>Increment Async</button></div>
Creates the Redux store, and allowconnect() to access it.
reducer(Function): A single reducer composed of all other reducers (create with redux.combineReducer)- [
middlewares] (Function[]): Optional, An array containing all the middleware that should be applied. Functions and strings are both valid members. String will be resolved via Angular, allowing you to use dependency injection in your middlewares. - [
storeEnhancers] (Function[]): Optional, this will be used to create the store, in most cases you don't need to pass anything, seeStore Enhancer official documentation. - [
initialState] (Object): Optional, the initial state of your Redux store.
Connects an Angular component to Redux.
mapStateToTarget(Function): connect will subscribe to Redux store updates. Any time it updates, mapStateToTarget will be called. Its result must be a plain object or a function returning a plain object, and it will be merged intotarget. If you have a component which simply triggers actions without needing any state you can pass null tomapStateToTarget.- [
mapDispatchToTarget] (Object orFunction): Optional. If an object is passed, each function inside it will be assumed to be a Redux action creator. An object with the same function names, but bound to a Redux store, will be merged ontotarget. If a function is passed, it will be givendispatch. It’s up to you to return an object that somehow usesdispatchto bind action creators in your own way. (Tip: you may use thebindActionCreators()helper from Redux.).
You then need to invoke the function a second time, withtarget as parameter:
target(Object orFunction): If passed an object, the results ofmapStateToTargetandmapDispatchToTargetwill be merged onto it. If passed a function, the function will receive the results ofmapStateToTargetandmapDispatchToTargetas parameters.
e.g:
connect(this.mapState,this.mapDispatch)(this);//Orconnect(this.mapState,this.mapDispatch)((selectedState,actions)=>{/* ... */});
Returns aFunction allowing to unsubscribe from further store updates.
- The
mapStateToTargetfunction takes a single argument of the entire Redux store’s state and returns an object to be passed as props. It is often called a selector. Use reselect to efficiently compose selectors and compute derived data. You can also choose to use per-instance memoization by having amapStateToTargetfunction returning a function of state, seeSharing selectors across multiple components
All of redux's store methods (i.e.dispatch,subscribe andgetState) are exposed by $ngRedux and can be accessed directly. For example:
$ngRedux.subscribe(()=>{letstate=$ngRedux.getState();//...})
This means that you are free to use Redux basic API in advanced cases whereconnect's API would not fill your needs.
You can use angularjs dependency injection mechanism to resolve dependencies inside amiddleware.To do so, define a factory returning a middleware:
functionmyInjectableMiddleware($http,anotherDependency){returnstore=>next=>action=>{//middleware's code}}angular.factory('myInjectableMiddleware',myInjectableMiddleware);
And simply register your middleware during store creation:
$ngReduxProvider.createStoreWith(reducers,[thunk,'myInjectableMiddleware']);
Middlewares passed asstring will then be resolved throught angular's injector.
You can debounce the digest triggered by store modification (usefull in huge apps with a lot of store modifications) by passing a config parameter to thengReduxProvider.
importangularfrom'angular';angular.module('ngapplication').config(($ngReduxProvider)=>{'ngInject';// eslint-disable-next-line$ngReduxProvider.config.debounce={wait:100,maxWait:500,};});
This will debounce the digest for 100ms with a maximum delay time of 500ms. Every store modification within this time will be handled by this delayed digest.
lodash.debounce is used for the debouncing.
Seeredux-ui-router to make ng-redux and UI-Router work together.
Seeng-redux-router to make ng-redux and angular-route work together.
There are two options for using Redux DevTools with your angular app. The first option is to use the [redux-devtools package] (https://www.npmjs.com/package/redux-devtools),and the other option is to use the [Redux DevTools Extension] (https://github.com/zalmoxisus/redux-devtools-extension#usage). The Redux DevTools Extension does notrequire adding the react, react-redux, or redux-devtools packages to your project.
To use the redux-devtools package, you need to installreact,react-redux andredux-devtools as development dependencies.
[...]import{devTools,persistState}from'redux-devtools';import{DevTools,DebugPanel,LogMonitor}from'redux-devtools/lib/react';importReact,{Component}from'react';angular.module('app',['ngRedux']).config(($ngReduxProvider)=>{$ngReduxProvider.createStoreWith(rootReducer,[thunk],[devTools()]);}).run(($ngRedux,$rootScope,$timeout)=>{React.render(<Appstore={$ngRedux}/>,document.getElementById('devTools'));//To reflect state changes when disabling/enabling actions via the monitor//there is probably a smarter way to achieve that$ngRedux.subscribe(()=>{$timeout(()=>{$rootScope.$apply(()=>{})},100);});});classAppextendsComponent{render(){return(<div><DebugPaneltoprightbottom><DevToolsstore={this.props.store}monitor={LogMonitor}/></DebugPanel></div>);}}
<body><divng-app='app'> [...]</div><divid="devTools"></div></body>
To use the Redux DevTools extension, you must first make sure that you have installed theRedux DevTools Extension.
angular.module('app',['ngRedux']).config(($ngReduxProvider)=>{$ngReduxProvider.createStoreWith(rootReducer,[thunk],[window.__REDUX_DEVTOOLS_EXTENSION__()]);}).run(($ngRedux,$rootScope,$timeout)=>{//To reflect state changes when disabling/enabling actions via the monitor//there is probably a smarter way to achieve that$ngRedux.subscribe(()=>{$timeout(()=>{$rootScope.$apply(()=>{})},100);});});
About
Angular bindings for Redux
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.