Skip to content

Instantly share code, notes, and snippets.

@paulfalgout
Created May 15, 2019 12:13
Show Gist options
  • Save paulfalgout/da6b54cb72acd4b5435d25bac8f473dd to your computer and use it in GitHub Desktop.
Save paulfalgout/da6b54cb72acd4b5435d25bac8f473dd to your computer and use it in GitHub Desktop.
combination of toolkit.app and backbone.eventrouter
import { _, Backbone, Radio } from 'VENDORS';
import EventRouter from './eventrouter';
import App from './app';
export default App.extend({
// Set in router apps for nav selection
routerAppName: '',
constructor() {
this.initRouter();
// if the app does not handle a given route, stop
this.listenTo(this.router, 'noMatch', this.onNoMatch);
App.apply(this, arguments);
},
initRouter() {
this._routes = _.result(this, 'eventRoutes');
const routeTriggers = this.getRouteTriggers();
this.router = new EventRouter({ routeTriggers });
this.bindRouteEvents();
},
onNoMatch() {
this.stop();
this._current = null;
this._currentRoute = null;
},
// For each route in the hash creates a routeTriggers hash
getRouteTriggers() {
return _.reduce(this._routes, function(routeTriggers, { route }, eventName) {
routeTriggers[eventName] = route;
return routeTriggers;
}, {});
},
getEventActions(eventRoutes, routeAction) {
return _.reduce(eventRoutes, function(eventActions, { action }, eventName) {
eventActions[eventName] = _.partial(routeAction, eventName, action);
return eventActions;
}, {});
},
// handle route events
// accepts a hash of 'some:event' : 'actionFunction'
// listens to the router channel and calls the appropriate
// action via the routeAction handler
bindRouteEvents() {
const eventActions = this.getEventActions(this._routes, this.routeAction);
this.listenTo(this.router.getChannel(), eventActions);
},
// applys the route's action
// starts this routerapp if necessary
// triggers before and after events
routeAction(event, action, ...args) {
if(!this.isRunning()) {
this.start();
}
this.triggerMethod('before:appRoute', event, ...args);
Radio.request('sidebar', 'close');
Radio.request('nav', 'select', this.routerAppName, event, args);
this.setLatestList(event, args);
this._currentRoute = {
event,
eventArgs: args
};
if(!_.isFunction(action)) {
action = this[action];
}
action.apply(this, args);
Backbone.history.trigger('current', event, ...args);
this.triggerMethod('appRoute', event, ...args);
},
setLatestList(event, eventArgs) {
if(this._routes[event].isPatientList) {
Radio.request('history', 'set:latestList', event, eventArgs);
return;
}
if(this._routes[event].hasLatestList) return;
Radio.request('history', 'set:latestList', false);
},
// handler that ensures one running app
startCurrent(appName, options) {
this.stopCurrent();
options = _.extend({
currentRoute: this._currentRoute
}, options);
const app = this.startChildApp(appName, options);
this._current = app;
return app;
},
getCurrent() {
return this._current;
},
stopCurrent() {
if(!this._current) return;
this._current.stop();
},
// takes an event and translates data into the applicable url fragment
translateEvent(event) {
const route = this.router.getDefaultRoute(event);
return this.router.translateRoute(route, _.rest(arguments));
},
// takes an event and changes the URL without triggering or adding to the history
replaceRoute() {
const url = this.translateEvent.apply(this, arguments);
Backbone.history.navigate(url, { trigger: false, replace: true });
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment