Skip to content

Instantly share code, notes, and snippets.

@rbergman
Created January 31, 2012 21:50
Show Gist options
  • Save rbergman/1713209 to your computer and use it in GitHub Desktop.
Save rbergman/1713209 to your computer and use it in GitHub Desktop.
A CoffeeScript Model base class providing declarative property support, with change listeners
{EventEmitter} = require "events"
# The Model base class
exports.Model = class Model
property = (k, events) ->
event = "change:#{k}"
fn = (v) =>
orig = if @_data[k]? then @_data[k] else null
if v is undefined then return orig
ret = if v then @_data[k] = v else delete @_data[k]
events.emit event, k, v, orig
ret
fn.onChange = (listener) =>
events.on event, => listener.apply @, arguments
@[k] = fn
@properties: (defaults) ->
@::_data = {}
em = new EventEmitter
property.call(@::, k, em)(v) for own k, v of defaults
@fromString: (json) -> @fromJSON JSON.parse(json)
@fromJSON: (json) ->
obj = new @
obj[k] v for own k, v of json if obj[k]?
obj
toString: (space) -> JSON.stringify @toJSON(), null, space
toJSON: -> @_data
# Example usage by a subclass
class Foo extends Model
@properties bar: "bar"
# Example usage of the subclass
foo = Foo.fromJSON {"bar":"baz"}
foo.bar.onChange (k, v, orig) -> console.log k, v, orig, @.toString()
console.log v for v in [
foo.toString() # {"bar":"bar"}
foo.bar() # bar
foo.bar("baz") # baz
foo.bar() # baz
foo.toString() # {"bar":"baz"}
foo.bar(null) # true
foo.bar() # null
foo.toString() # {}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment