class State constructor: -> super @_bindEvent(eventSpec, fnName) for eventSpec, fnName of _.result(@, 'events', {}) @ _bindEvent: (eventSpec, fnName) -> [kp, events...] = eventSpec.split(' ') if _.isEmpty(events) @on(kp, @[fnName]) else @listenTo(_.get(@, kp), events.join(' '), @[fnName]) isState: true dataTypes: function: set: (fn) -> if _.isBlank(fn) or _.isFunction(fn) { val: fn, type: 'function' } else throw new TypeError element: set: (el) -> if _.isBlank(el) or _.isElement(el) { val: el, type: 'element' } else throw new TypeError collection: set: (c) -> if _.isBlank(c) or Lanes.u.isCollection(c) or _.isArray(c) { val: c, type: 'collection' } else throw new TypeError code: set: (newVal) -> newVal = '' if !newVal? if _.isString(newVal) val: newVal.toUpperCase(), type: 'code' else throw new TypeError('code must be a string') default: -> '' # Big decimal for attributes that need precision math bigdec: set: (newVal) -> try val = _.bigDecimal(newVal) { val, type: 'bigdec' } catch {val: newVal} default: -> new _.bigDecimal(0) integer: set: (newVal) -> val = switch when _.isInteger(newVal) then newVal when ! _.isBlank(newVal) then parseInt(newVal, 10) else undefined {val, type: 'integer'} file: set: (val) -> type = if _.isObject(val) then 'file' else typeof val if _.isBlank(val) val = null type = 'file' return { val, type } default: -> {} moment: get: (val) -> _.moment(val) default: -> _.moment() set: (newVal) -> { val: _.moment(newVal), type: 'moment' } compare: (currentVal, newVal) -> currentVal.isSame(newVal) # Uses the "moment" lib to parse dates and coerce strings into the date type. date: get: (val) -> new Date(val) default: -> return new Date() set: (newVal) -> if _.isDate(newVal) type = 'date' val = new Date(newVal) else if newVal m = Lanes.Vendor.Moment(Date.parse(newVal)) if m.isValid() type = 'date' val = m.toDate() else type = typeof newVal; return { type, val } # ## listenToAndRun # Shortcut for registering a listener for a model # and also triggering it right away. listenToAndRun: (object, events, handler) -> bound = _.bind(handler, this) this.listenTo(object, events, bound) bound() Lanes.Models.State = Lanes.lib.MakeBaseClass( Lanes.Vendor.Ampersand.State, State )