Skip to content

Instantly share code, notes, and snippets.

@facugon
Last active January 20, 2017 20:14
Show Gist options
  • Save facugon/759b8a45b786357fd58aaac395d03752 to your computer and use it in GitHub Desktop.
Save facugon/759b8a45b786357fd58aaac395d03752 to your computer and use it in GitHub Desktop.
a POC of an store using backbone.collections implementing a flux dispatcher
'use strict';
(function Dispatcher(){
window.App||(window.App={});
var _prefix = 'ID_';
var Dispatcher = function(){
if (!this instanceof Dispatcher) {
return new Dispatcher();
}
_.extend(this, Backbone.Events);
this._callbacks = {};
this._isDispatching = false;
this._isHandled = {};
this._isPending = {};
this._lastID = 1;
}
/**
* https://github.com/facebook/flux/blob/master/src/Dispatcher.js
*/
Dispatcher.prototype = {
_startDispatching: function (payload) {
for (var id in this._callbacks) {
this._isPending[id] = false;
this._isHandled[id] = false;
}
this._pendingPayload = payload;
this._isDispatching = true;
},
_stopDispatching: function() {
delete this._pendingPayload;
this._isDispatching = false;
},
_invokeCallback: function(id) {
this._isPending[id] = true;
this._callbacks[id](this._pendingPayload);
this._isHandled[id] = true;
},
dispatch: function(payload) {
if (this._isDispatching) {
var msg = 'Dispatcher.dispatch(...): Cannot dispatch in the middle of a dispatch.';
throw new Error(msg);
}
this._startDispatching(payload);
try {
for (var id in this._callbacks) {
if (this._isPending[id]) {
continue;
}
this._invokeCallback(id);
}
} finally {
this._stopDispatching();
}
},
isDispatching: function() {
return this._isDispatching;
},
register: function(callback){
var id = _prefix + this._lastID++;
this._callbacks[id] = callback;
return id;
},
unregister: function(id) {
delete this._callbacks[id];
}
}
window.App.Dispatcher = new Dispatcher();
})();
'use strict';
var FileActions = {
create: function(data,source){
App.EventsDispatcher.dispatch({
actionType: App.Constants.FILE_CREATE,
properties: data,
source: source
});
},
update: function(id,data,source){
App.EventsDispatcher.dispatch({
actionType: App.Constants.FILE_UPDATE,
id: id,
properties: data,
source: source
});
},
remove: function(id){
App.EventsDispatcher.dispatch({
actionType: App.Constants.FILE_REMOVE,
id: id
});
}
};
'use strict';
//var App = require('app');
var FilesStore = (function(){
var files = new App.Collections.Files();
function create (properties, source) {
var file = new App.Models.File();
file.set(properties);
var source = btoa(unescape(encodeURIComponent(source)));
file.set('file',source);
file.upload({},{
success: function(model, response, options){
files.add(file);
store.emitChange();
},
error: function(model, response, options){
}
});
}
function update (id, properties, source) {
}
function remove (id) {
}
files.fetch();
var store = _.extend({},Backbone.Events,{
/**
*
*/
emitChange: function(){
this.trigger(App.Constants.CHANGE_EVENT);
},
/**
*
*/
addChangeListener: function(callback,context) {
this.on(App.Constants.CHANGE_EVENT, callback, context);
return this;
},
/**
*
*/
removeChangeListener: function(callback) {
this.off(App.Constants.CHANGE_EVENT, callback);
return this;
}
});
Object.defineProperty(store,'files',{
get:function(){
return files.clone(); // the original files collection is private and cannot be modified
}
});
var id = window.App.EventsDispatcher.register(
function(action){
switch (action.actionType) {
case App.Constants.FILE_CREATE:
create(action.properties,action.source);
break;
case App.Constants.FILE_UPDATE:
update(action.id,action.properties,action.source);
break;
case App.Constants.FILE_REMOVE:
remove(action.id);
break;
default:
// no op
}
}
);
return store;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment