Skip to content

Instantly share code, notes, and snippets.

@ianmstew
Last active August 29, 2015 14:06
Show Gist options
  • Save ianmstew/6f0e85eff41bbe6a09bd to your computer and use it in GitHub Desktop.
Save ianmstew/6f0e85eff41bbe6a09bd to your computer and use it in GitHub Desktop.
define(function (require) {
var Mixin = require('lib/classes/mixin');
var Radio = require('backbone.radio');
var logger = require('lib/util/logger');
var HasChannel = Mixin.extend({
// Declarative option for channel name
// channelName: nameOfChannel
// Declarative binding of channel events
// channelEvents: {
// 'event': ['on|reply|comply', eventHandler]
// }
// Current channel
channel: null,
initialize: function (options) {
this.channelName = this.channelName || (options || {}).channelName;
this.channel = Radio.channel(this.channelName);
if (this.channelEvents) this._registerChannelEvents();
},
_registerChannelEvents: function (channelEvents) {
_.each(this.channelEvents, this._registerChannelEvent, this);
},
_registerChannelEvent: function (channelHandler, event) {
var eventType = channelHandler[0];
var eventHandler = this[channelHandler[1]];
switch (eventType) {
case 'on':
this.listenTo(this.channel, event, eventHandler);
break;
case 'reply':
this.replyWith(this.channel, event, eventHandler);
break;
case 'comply':
this.complyWith(this.channel, event, eventHandler);
break;
default:
logger.warn(eventType + ' is not supported');
break;
}
}
});
return HasChannel;
});
define(function (require) {
var Mixin = require('lib/classes/mixin');
var Backbone = require('backbone');
var Marionette = require('marionette');
var HasState = Mixin.extend({
// Default state overridable by constructor 'state' option
// defaultState: null,
// Backbone model maintaining state
state: null,
// Initial state of model after defaults and constructor 'state' option
initialState: null,
initialize: function (options) {
_.bindAll(this, '_cleanupState');
var state = (options || {}).state;
if (state && state instanceof Backbone.Model) {
this.state = state;
} else {
this.initialState = _.defaults({}, state, this.defaultState);
this.state = new Backbone.Model(this.initialState);
}
if (this.stateEvents) this._attachStateEvents();
if (this.serializeData) this._wrapSerializeData();
this.on('destroy', this._cleanupState);
},
setState: function () {
return this.state.set.apply(this.state, arguments);
},
getState: function () {
return this.state.get.apply(this.state, arguments);
},
_attachStateEvents: function () {
Marionette.bindEntityEvents(this, this.state, this.stateEvents);
},
_detachStateEvents: function () {
Marionette.unbindEntityEvents(this, this.state, this.stateEvents);
},
_wrapSerializeData: function () {
this.serializeData = _.wrap(this.serializeData, this._serializeDataWrapper);
},
_serializeDataWrapper: function (serializeData) {
var origArgs = Array.prototype.slice.call(this, 1);
var data = serializeData.apply(this, origArgs);
data.state = this.state.toJSON();
return data;
},
resetState: function () {
this.state.set(this.initialState, { unset: true });
},
_cleanupState: function () {
if (this.stateEvents) this._detachStateEvents();
this.state.destroy();
this.state = null;
}
});
return HasState;
});
<a class="{{#state.selected}}selected{{/state.selected}}" href="/apps/{{appID}}/{{name}}">
{{title}}
</a>
define(function (require) {
var Marionette = require('marionette');
var template = require('hgn!modules/editor/child-views/tab.view');
var HasState = require('lib/mixin/has-state');
var HasChannel = require('lib/mixin/has-channel');
var TabView = Marionette.ItemView.extend({
channelName: 'editor',
template: template,
tagName: 'li',
channelEvents: {
'show:tab': ['on', 'tabShown']
},
stateEvents: {
'change': 'render'
},
initialize: function (options) {
this.initializeMixins(options);
},
tabShown: function (tab) {
var selected = this.model.get('name') === tab;
this.state.set('selected', selected);
},
serializeData: function () {
var data = TabView.__super__.serializeData.apply(this, arguments);
data.appID = this.channel.request('appId');
return data;
}
});
HasState.mixInto(TabView);
HasChannel.mixInto(TabView);
return TabView;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment