Table of Contents:
- Why FLUX?
- About this Guide
- Library Dependencies
- Directory Structure
- store.js
- constants.js
- dispatcher.js
- actions.js
- app.js
I prefer the FLUX pattern to MVC, and I have been successful in applying the FLUX pattern without running into too much trouble.
This mini-howto guide is intended for an audience with experience using FLUX. My personal experience with flux may easily be lesser than some of those reading. Please assume that I am happy to be corrected, should this guide imply anything that may be detrimental (other than using flux on its own of course ;))
Should there be a large enough audience, I will write a more comprehensive guide.
- Mithril.js - Of course!
- Bullet - an ultra-lightweight event emitter (0.975 kB minified, smaller when gzipped)
- MSX support (I currently just use Browserify/Mithrilify, but I think babelify could be used later)
The React or Flux API libraries are NOT used.
My filebase currently is comprised like so, (this is not optimized for scalability, as this is an experiment)
src/
actions.js
constants.js
dispatcher.js
index.js (browserify entry point)
store.js
src/components
...
app.js
var Bullet = require('bullet-pubsub'),
Constants = require('./constants'),
_data = { showSidebar: false};
var Store = {
getAll: function () {
return {data: _data};
},
// Allow Controller-View to register itself with store
addChangeListener: function (callback) {
Bullet.on(Constants.CHANGE_EVENT, callback);
},
removeChangeListener: function (callback) {
Bullet.removeListener(Constants.CHANGE_EVENT, callback);
},
// triggers change listener above, firing controller-view callback
emitChange: function () {
Bullet.trigger(Constants.CHANGE_EVENT);
},
dispatchIndex: function (payload) {
console.log('PAYLOAD:', payload);
switch (payload.type) {
case Constants.ActionTypes.TEST_STORE:
_data.message='test store works';
Store.emitChange();
break;
case Constants.ActionTypes.SHOW_SIDEBAR:
_data.showSidebar = true;
Store.emitChange();
break;
case Constants.ActionTypes.HIDE_SIDEBAR:
_data.showSidebar = false;
Store.emitChange();
break;
}
}
};
module.exports = Store;
module.exports = {
CHANGE_EVENT: 'CHANGE_EVENT',
ActionTypes: {
TEST_STORE: 'TEST_STORE',
SHOW_SIDEBAR: 'SHOW_SIDEBAR',
HIDE_SIDEBAR: 'HIDE_SIDEBAR'
}
};
var Store = require('./store');
module.exports = function (payload) {
Store.dispatchIndex(payload);
};
var Constants = require('./constants');
var Dispatcher = require('./dispatcher');
module.exports = {
testStore: function (data) {
Dispatcher({
type: Constants.ActionTypes.TEST_STORE,
data: data
})
},
showSidebar: function () {
Dispatcher({
type: Constants.ActionTypes.SHOW_SIDEBAR
});
},
hideSidebar: function () {
Dispatcher({
type: Constants.ActionTypes.HIDE_SIDEBAR
});
}
};
require('./app.less');
// Framework
var Store = require('../store'),
Actions = require('../actions');
// Sub-Components
var TopNav = require('./topnav'),
Sidebar = require('./sidebar'),
PostList = require('./PostList');
var App = {
state: {
data: {}
},
_onChange: function () {
App.state = Store.getAll();
},
controller: function() {
return {
onunload: function () {
Store.removeChangeListener(App._onChange);
}
}
},
view: function(ctrl) {
return (
<div>
<TopNav/>
<Sidebar/>
<div class="container-fluid">
<PostList/>
</div>
</div>
)
}
};
Store.addChangeListener(App._onChange);
module.exports = App;
Are you have the topnav, sidebar, PostList and app.less element ?