Skip to content

Instantly share code, notes, and snippets.

Created August 31, 2012 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/3556551 to your computer and use it in GitHub Desktop.
Save anonymous/3556551 to your computer and use it in GitHub Desktop.
observable with computed fields
var Model = require('./')
var m = new Model()
var n = new Model()
n.compute('change', function (time, name) {
return 'changed name to:' + name + ' at ' + time
}, [ [m, 'time'], 'name' ])
n.on('change:change', console.log)
setInterval(function () {
m.set('time', new Date())
}, 233)
setInterval(function () {
n.set('name', Math.random() < 0.5 ? 'jim' : 'bob')
}, 533)
var EE = require('events').EventEmitter
var inherits = require('util').inherits
module.exports = Model
inherits(Model, EE)
function Model () {
this._store = {}
this._localStore = {}
}
var m = Model.prototype
m.set = function (key, value) {
this._store[key] = value
this.emit('change', key, value)
this.emit('change:'+key, value)
return this
}
m.setLocal = function (key, value) {
this._localStore[key] = value
this.emit('change', key, value, true)
this.emit('change:'+key, value, true)
return this
}
m.get = function (key) {
return this._localStore[key] == null ? this._store[key] : this._localStore[key]
}
function isObservable (o) {
return (
o
&& 'object' === typeof o
&& 'function' === typeof o.on
&& 'function' === typeof o.get
)
}
m.compute = function (name, func, attrs) {
var args = new Array(attrs.length), set = new Array(attrs.length)
var self = this
var _update = false
function key(i, v) {
args[i] = v
set[i] = true
update()
}
function update() {
if(_update) return
_update = true
process.nextTick(function () {
_update = false
var l = set.length
while(l--) //wait until all the args are ready to go.
if(!set[l]) return
self.setLocal(name, func.apply(self, args))
})
}
attrs.forEach(function (attr, i) {
if('string' === typeof attr)
self.on('change:'+attr, function (val) {
key(i, val)
})
else if(isObservable(attr))
attr.on('change', function (val) {
key(i, attr)
})
else if(Array.isArray(attr)) {
console.log('AARY', attr)
attr[0].on('change:'+attr[1], function (val) {
key(i, val)
})
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment