Skip to content

Instantly share code, notes, and snippets.

@michal
Created March 11, 2016 15:18
Show Gist options
  • Save michal/1d5517901c8c8dbec785 to your computer and use it in GitHub Desktop.
Save michal/1d5517901c8c8dbec785 to your computer and use it in GitHub Desktop.
bacbone like models with pubsub
import _ from 'lodash'
import Events from './events'
export default class Entity {
constructor(defaults) {
this.$events = new Events()
this.$original = {}
this.$changed = []
this._attributes = {}
this.$attributes = {}
let _set = (source, key, value, namespace) => {
if (_.has(this.$original, namespace)) {
if (this.$original[namespace] === value) {
this.$events.publish(`reset:${namespace}`, value)
_.remove(this.$changed, (value) => value === namespace)
} else {
this.$events.publish(`update:${namespace}`, value)
this.$changed.push(namespace)
this.$changed = _.uniq(this.$changed)
}
} else {
this.$original[namespace] = value
}
this.$events.publish(`change:${namespace}`, this, key, value)
source[key] = value
}
let _get = (source, key, namespace) => {
return source[key]
}
let _assign = (parameters, target, source, parent = '') => {
for (let key in parameters) {
let namespace = parent ? `${parent}.${key}` : key
if (_.isObject(parameters[key])) {
_assign(parameters[key], target[key] = {}, source[key] = {}, namespace)
} else {
Object.defineProperty(target, key, {
enumerable: true,
set: (value) => _set(source, key, value, namespace),
get: () => _get(source, key, namespace)
})
}
}
}
_assign(defaults, this.$attributes, this._attributes)
}
}
import _ from 'lodash'
export default class Events {
constructor() {
this._events = {}
this._log = false
}
log(task, value) {
if (this._log) {
console.log(`Events:${task}`, value)
}
}
subscribe(name, callback, context) {
this.log(`subscribe:${name}`)
name = name + ''
let events = this._events[name] || (this._events[name] = [])
events.push({callback: callback, context: context || this})
return this
}
unsubscribe(name) {
this.log(`unsubscribe:${name}`)
if (this._events[name]) {
delete this._events[name]
}
}
publish(name, ...args) {
if (!_.isEmpty(this._events)) {
let queue = this._events[name]
this.log(`publish:${name}`, args)
for (let i in queue) {
let task = queue[i]
task.callback.apply(task.context, args)
}
}
return this
}
empty() {
this._events = {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment