Skip to content

Instantly share code, notes, and snippets.

@wegorich
Created September 12, 2016 16:01
Show Gist options
  • Save wegorich/5d1fabc550fb3f01e0a57d3d4308294a to your computer and use it in GitHub Desktop.
Save wegorich/5d1fabc550fb3f01e0a57d3d4308294a to your computer and use it in GitHub Desktop.
Using the Aurelia with Redux
export class BaseVM {
_syncInit() {
this._sync();
this._unsubscribe = this.store.subscribe(this._sync.bind(this));
}
_syncUnsubscribe() {
this._unsubscribe();
}
_sync() {
this.sync(this.store.getState());
}
getLoading(state, name) {
name = name.toLowerCase();
return !!state.loaders.find(e => e.toLowerCase().replace(/_/g, '').endsWith(name));
}
showErrors(state) {
if (state.errors.length > 0) {
let err = state.errors[state.errors.length - 1];
console.log('error', err);
let message = err.message ||
err.data && err.data.error;
if (message)
this.toast.error(message);
this.clearErrors();
}
}
// the sync sould be overrided;
//
sync(state) {}
// it also can be overrided
// please use super.bind in this situation
//
bind() {
this._syncInit();
}
unbind() {
this._syncUnsubscribe();
}
}
import { inject } from 'aurelia-framework'
import { bindActionCreators } from 'redux'
export const createDependencies = (store, actionCreators) => {
const actionsCallbacks =
bindActionCreators(actionCreators, store.dispatch)
return [store, actionsCallbacks]
}
export const createDecroator = store => (actionCreators, ...injectParams) => {
const actionsCallbacks =
bindActionCreators(actionCreators, store.dispatch)
return inject(store, actionsCallbacks, ...injectParams)
}
import { createStore, applyMiddleware, combineReducers } from 'redux'
import promiseMiddleware from 'gl/promise-middleware'
export default function(data, reducers) {
var reducer = combineReducers(reducers)
var finalCreateStore = applyMiddleware(promiseMiddleware)(createStore)
var store = finalCreateStore(reducer, data, window.devToolsExtension && window.devToolsExtension())
return store
}
import api from './api';
// async with easy chaning syntax
// getX(data).then(getY.bind(this, data)).then(getZ);
export function getX(data) {
return Object.assign(api.getX(data), {
type: Const.GET_X,
params: data
});
}
// async without chaning
export function getY(data) {
return {
type: Const.GET_Y,
params: data,
promise: () => {
return api.getY(data);
}
}
}
// common
export function getZ() {
return {
type: Const.GET_Y,
params: {z: 'z'}
}
}
import { bindable, inject } from 'aurelia-framework';
import { activationStrategy } from 'aurelia-router';
import { decorator, BaseVM, actions } from 'some/store';
@decorator(actions)
export class SomeManager extends BaseVM {
constructor(store, { getX, getY }) {
super();
this.store = store;
this.getX = getX;
this.getY = getY;
this.reset();
}
sync(state) {
this.x = state.x;
this.y = state.y;
this.params.xLoading = this.getLoading(state, 'x');
this.params.yLoading = this.getLoading(state, 'y');
}
activate(params, routeConfig, navigationInstruction) {
this.getX(this.params).then(()=> this.getY(this.params));
}
reset() {
this.params = {
yLoading: false,
xLoading: false
}
}
}
export default function promiseMiddleware() {
return (next) => (action) => {
const { promise, type, ...rest } = action;
if ('function' === typeof action.then) {
// it's promise
//
next({...rest, type: `${type}_REQUEST` })
// new way working with promises
return action.then(
(result) => {
next({...rest, result, type: type })
},
(error) => {
next({...rest, error, type: `${type}_FAILURE` })
}
)
} else {
if (!promise) {
return next(action)
}
// old way working with promises
next({...rest, type: `${type}_REQUEST` })
return promise().then(
(result) => {
next({...rest, result, type: type })
},
(error) => {
next({...rest, error, type: `${type}_FAILURE` })
}
)
}
}
}
// just set up redux store as normal
import createStore from "./create-store"
import { createDecroator } from './create-decorator'
import { BaseVM } from './base-vm'
const plugins = [
'base/module',
];
let modules = plugins.map(e => require(e))
.reduce((prev, current) => {
Object.assign(prev.reducers, current.reducers);
Object.assign(prev.actions, current.actions);
Object.assign(prev.routes, current.routes);
return prev;
}, { reducers: {}, actions: {}, routes: {} });
export const store = createStore({}, modules.reducers);
export const actions = modules.actions;
export const routes = modules.routes;
// setting up your decorator
export const decorator = createDecroator(store)
// export const module = createModule(store)
export { BaseVM }
export function registerAppPlugins(aurelia, routesFactory, permissionsRegistry) {
plugins.forEach(name => {
aurelia.use.plugin(name, config => {
if (config.routes)
routesFactory.registerRoutes(name, config.routes);
if (config.permissions)
permissionsRegistry.registerPermissions(Object.keys(config.permissions));
});
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment