Skip to content

Instantly share code, notes, and snippets.

@wegorich
Last active October 4, 2017 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wegorich/d3ec7dd2fe324697bf0d37d3d5caece8 to your computer and use it in GitHub Desktop.
Save wegorich/d3ec7dd2fe324697bf0d37d3d5caece8 to your computer and use it in GitHub Desktop.
example of usage redux in aurelia.js
// Cause we use `redux-pirate-actions` the actions can be just a functions returned something Object / Promises...
export function clearErrors(data) {
}
export function setRoute(route) {
return {
route: route
};
}
export function loadUsers(breadcrumbs) {
return Promise.resolve({data: [{name: 'userName'}, {name: 'userName1'], total: 2});
}
// Let's make the general code in our controllers more robust
// and hide the all subscriptions to store with the base class.
export class BaseVM {
_syncInit() {
this._syncUnsubscribe();
this._sync();
this._unsubscribe = this.store.subscribe(this._sync.bind(this));
}
_syncUnsubscribe() {
this._unsubscribe && this._unsubscribe();
this._unsubscribe = null;
}
_sync() {
this.sync(this.store.getState());
}
getLoading(state, name) {
name = name.toLowerCase();
return !!state.loaders.find(e => e.toLowerCase().replace(/_/g, '').endsWith(name));
}
// the sync sould be overrided;
//
sync(state) {}
// it also can be overrided
// please use super.bind in this situation
//
bind() {
this._syncInit();
}
// this kind of optimization
// cause bind / unbind never trigger more then once for views
attached() {
this._syncInit();
}
// this kind of optimization
detached() {
this._syncUnsubscribe();
}
unbind() {
this._syncUnsubscribe();
}
}
// Cause we use `redux-pirate-actions` we can receive the actions names with the `getTypes`
// function or get them from the `window.types`.
import { getTypes } from 'redux-pirate-actions';
const types = getTypes();
// or types can come from window object
export function route(state = {}, action) {
switch (action.type) {
case types.setRoute:
return {
...action.route
}
default:
return state;
}
}
// example of fetching action pending actions to show loaders
export function loaders(state = [], action) {
let type = action.type.replace('Error', '');
if (type.endsWith('Request')) {
return [...state, type.replace('Request', '')];
}
if (~state.indexOf(type)) {
state.splice(state.indexOf(type), 1);
return [...state];
}
return state;
}
// example of global error handling
export function errors(state = [], action) {
if (action.type.endsWith('Error')) {
return [...state, action.error];
}
if (action.type === types.clearErrors) {
return [];
}
return state;
}
export function users(state = { data: [], total: 0 }, action) {
switch (action.type) {
case types.loadUsers:
return {
data: action.result.data,
total: action.result.total,
}
default:
return state;
}
}
// At last we receive the beautiful code in our controller and now we able to work with store easy way.
import { decorator } from '~/src/store/index';
import { BaseVM } from '~/src/services/index';
import moment from 'moment';
@decorator(moment)
export class Vm extends BaseVM {
constructor(store, actions, moment) {
super();
this.store = store;
this.actions = actions;
this.moment = moment;
this.reset();
}
sync(state) {
this.params.loading = this.getLoading(state, 'users');
this.users = state.users;
}
activate(params) {
this.loadUsers(this.params);
}
change() {
this.loadUsers(this.params);
}
reset() {
this.params = {
loading: true,
users: []
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment