Created
January 26, 2015 14:56
-
-
Save zerkalica/a160a67ef3297ab156a0 to your computer and use it in GitHub Desktop.
Semantic actions store example for flux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ActionsBase { | |
constructor(dispatcher) { | |
this.dispatcher = dispatcher | |
this.key = null | |
} | |
_dispatch(data, suffix) { | |
this.dispatcher.dispatch(this.key + suffix, data) | |
} | |
dispatch(fn) { | |
this._dispatch(fn(), '') | |
} | |
dispatchAsync(fn) { | |
this._dispatch(null, 'Progress') | |
fn() | |
.then((payload) => this._dispatch(payload, 'Success')) | |
.catch((err) => this._dispatch(err, 'Fail')) | |
} | |
} | |
function getActionsConstants(proto) { | |
let constants = proto.__constants__ | |
if (constants) { | |
return constants | |
} | |
constants = proto.__constants__ = [] | |
let obj = proto.prototype | |
let key | |
let actionType | |
let fakeObj = { | |
dispatch() { | |
constants.push(key) | |
}, | |
dispatchAsync() { | |
constants.push(key + 'Progress') | |
constants.push(key + 'Success') | |
constants.push(key + 'Fail') | |
} | |
} | |
for (let name in obj) { | |
if (!obj.hasOwnProperty(name)) continue | |
let fn = obj[name] | |
key = name | |
fn.apply(fakeObj) | |
obj[name] = function() { | |
this.key = name | |
return fn.apply(this, arguments) | |
} | |
} | |
return constants | |
} | |
function getActionSetsConstants(prototypes) { | |
let result = [] | |
if (!Array.isArray(prototypes)) prototypes = [prototypes] | |
for(let i = 0; i < prototypes.length; i++) { | |
let constants = getActionsConstants(prototypes[i]) | |
result = result.concat(constants) | |
} | |
return result | |
} | |
class StoreBase { | |
constructor(dispatcher) { | |
this.dispatcher = dispatcher | |
this.initialize() | |
} | |
initialize () { | |
let constants = getActionSetsConstants(this.getActions()); | |
for (let i = 0; i < constants.length; i++) { | |
let message = constants[i] | |
if(typeof this[message] !== 'function') continue | |
this.dispatcher.on(message, this[message].bind(this)) | |
} | |
} | |
} | |
class Dispatcher { | |
constructor() { | |
this.listeners = new Map() | |
} | |
dispatch(message, payload) { | |
this.listeners.get(message).forEach((fn) => { | |
fn(payload) | |
}) | |
} | |
on(message, fn) { | |
if (!this.listeners.has(message)) this.listeners.set(message, []) | |
this.listeners.get(message).push(fn) | |
} | |
} | |
class MyActions extends ActionsBase { | |
addItemSync(item) { | |
this.dispatch(() => { | |
let value = 123 | |
return item.test+ value | |
}) | |
} | |
addItem(item) { | |
this.dispatchAsync(() => { | |
return new Promise((resolve, reject) => { | |
let value = 123 | |
resolve(item.test + value) | |
}) | |
}) | |
} | |
} | |
class MyStore extends StoreBase { | |
getActions() { | |
return [MyActions] | |
} | |
addItemSync(item) { | |
console.log('addItemSync:', item) | |
} | |
addItemProgress(item) { | |
console.log('addItemProgress:', item) | |
} | |
addItemSuccess(item) { | |
console.log('addItemSuccess:', item) | |
} | |
} | |
let dispatcher = new Dispatcher() | |
let myStore = new MyStore(dispatcher) | |
let myActions = new MyActions(dispatcher) | |
myActions.addItemSync({test: 'sync'}) | |
myActions.addItem({test: 'async'}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment