Upgrade to spinejs 1.4.1.

This commit is contained in:
Martin Edenhofer 2015-04-13 15:02:44 +02:00
parent 04480db9aa
commit acc6f606f8
4 changed files with 83 additions and 98 deletions

View file

@ -213,18 +213,15 @@ class Singleton extends Base
Ajax.disable => Ajax.disable =>
unless Spine.isBlank(data) or @record.destroyed unless Spine.isBlank(data) or @record.destroyed
# ID change, need to do some shifting
if data.id and @record.id isnt data.id
@record.changeID(data.id)
# Update with latest data # Update with latest data
@record.refresh(data) @record.refresh(data)
@record.trigger('ajaxSuccess', data, status, xhr) @record.trigger('ajaxSuccess', @record, @model.fromJSON(data), status, xhr)
options.done?.apply(@record) options.done?.apply(@record)
failResponse: (options = {}) => failResponse: (options = {}) =>
(xhr, statusText, error) => (xhr, statusText, error) =>
@record.trigger('ajaxError', xhr, statusText, error) @record.trigger('ajaxError', @record, xhr, statusText, error)
options.fail?.apply(@record) options.fail?.apply(@record)
# Ajax endpoint # Ajax endpoint
@ -265,7 +262,7 @@ Model.Ajax =
ajaxChange: (record, type, options = {}) -> ajaxChange: (record, type, options = {}) ->
return if options.ajax is false return if options.ajax is false
record.ajax()[type](options.ajax, options) record.ajax()[type]?(options.ajax, options)
Model.Ajax.Methods = Model.Ajax.Methods =
extended: -> extended: ->

View file

@ -22,23 +22,23 @@ class ValueSetter
getter element getter element
_standardGetter: (element) -> _standardGetter: (element) ->
self = @ self = this
self["_#{element.attr("type")}Get"]?(element) || element.val() self["_#{element.attr('type')}Get"]?(element) || element.val()
_standardSetter: (element, value) -> _standardSetter: (element, value) ->
self = @ self = this
element.each -> element.each ->
el = $(this) el = $(this)
self["_#{el.attr("type")}Set"]?(el, value) || el.val(value) self["_#{el.attr('type')}Set"]?(el, value) || el.val(value)
_checkboxSet: (element, value) -> _checkboxSet: (element, value) ->
if value if value
element.prop("checked", "checked") element.prop('checked', 'checked')
else else
element.prop("checked", "") element.prop('checked', '')
_checkboxGet: (element) -> _checkboxGet: (element) ->
element.is(":checked") element.is(':checked')
BindingsInstance = BindingsInstance =

View file

@ -69,11 +69,8 @@ class Instance extends Spine.Module
for key, value of options for key, value of options
@[key] = value @[key] = value
exists: ->
return if @record[@fkey] then @model.exists(@record[@fkey]) else false
find: -> find: ->
return @model.find(@record[@fkey]) @model.find(@record[@fkey])
update: (value) -> update: (value) ->
return this unless value? return this unless value?

View file

@ -6,7 +6,7 @@ Released under the MIT License
Events = Events =
bind: (ev, callback) -> bind: (ev, callback) ->
evs = ev.split(' ') evs = ev.split(' ')
@_callbacks = {} unless @hasOwnProperty('_callbacks') and @_callbacks @_callbacks or= {} unless @hasOwnProperty('_callbacks')
for name in evs for name in evs
@_callbacks[name] or= [] @_callbacks[name] or= []
@_callbacks[name].push(callback) @_callbacks[name].push(callback)
@ -18,12 +18,11 @@ Events =
callback.apply(this, arguments) callback.apply(this, arguments)
trigger: (args...) -> trigger: (args...) ->
ev = args.shift() ev = args.shift()
list = @hasOwnProperty('_callbacks') and @_callbacks?[ev] list = @_callbacks?[ev]
return unless list return unless list
for callback in list for callback in list
if callback.apply(this, args) is false break if callback.apply(this, args) is false
break
true true
listenTo: (obj, ev, callback) -> listenTo: (obj, ev, callback) ->
@ -37,11 +36,11 @@ Events =
obj.bind ev, handler = -> obj.bind ev, handler = ->
idx = -1 idx = -1
for lt, i in listeningToOnce when lt.obj is obj for lt, i in listeningToOnce when lt.obj is obj
idx = i if lt.ev is ev and lt.callback is callback idx = i if lt.ev is ev and lt.callback is handler
obj.unbind(ev, handler) obj.unbind(ev, handler)
listeningToOnce.splice(idx, 1) unless idx is -1 listeningToOnce.splice(idx, 1) unless idx is -1
callback.apply(this, arguments) callback.apply(this, arguments)
listeningToOnce.push {obj, ev, callback, handler} listeningToOnce.push {obj, ev, callback: handler}
this this
stopListening: (obj, events, callback) -> stopListening: (obj, events, callback) ->
@ -49,7 +48,7 @@ Events =
for listeningTo in [@listeningTo, @listeningToOnce] for listeningTo in [@listeningTo, @listeningToOnce]
continue unless listeningTo continue unless listeningTo
for lt in listeningTo for lt in listeningTo
lt.obj.unbind(lt.ev, lt.handler or lt.callback) lt.obj.unbind(lt.ev, lt.callback)
@listeningTo = undefined @listeningTo = undefined
@listeningToOnce = undefined @listeningToOnce = undefined
@ -60,16 +59,18 @@ Events =
for ev in events for ev in events
for idx in [listeningTo.length-1..0] for idx in [listeningTo.length-1..0]
lt = listeningTo[idx] lt = listeningTo[idx]
continue if callback and (lt.handler or lt.callback) isnt callback continue unless lt.obj is obj
continue if callback and lt.callback isnt callback
if (not ev) or (ev is lt.ev) if (not ev) or (ev is lt.ev)
lt.obj.unbind(lt.ev, lt.handler or lt.callback) lt.obj.unbind(lt.ev, lt.callback)
listeningTo.splice(idx, 1) unless idx is -1 listeningTo.splice(idx, 1) unless idx is -1
else if ev else if ev
evts = lt.ev.split(' ') evts = lt.ev.split(' ')
if ev in evts if ev in evts
evts = (e for e in evts when e isnt ev) evts = (e for e in evts when e isnt ev)
lt.ev = $.trim(evts.join(' ')) lt.ev = $.trim(evts.join(' '))
lt.obj.unbind(ev, lt.handler or lt.callback) lt.obj.unbind(ev, lt.callback)
this
unbind: (ev, callback) -> unbind: (ev, callback) ->
if arguments.length is 0 if arguments.length is 0
@ -90,7 +91,7 @@ Events =
break break
this this
Events.on = Events.bind Events.on = Events.bind
Events.off = Events.unbind Events.off = Events.unbind
Log = Log =
@ -132,6 +133,7 @@ class Module
class Model extends Module class Model extends Module
@extend Events @extend Events
@include Events
@records : [] @records : []
@irecords : {} @irecords : {}
@ -158,21 +160,20 @@ class Model extends Module
@exists: (id) -> Boolean @irecords[id] @exists: (id) -> Boolean @irecords[id]
@addRecord: (record, options = {}) -> @addRecord: (record) ->
if record.id and @irecords[record.id] if root = @irecords[record.id or record.cid]
@irecords[record.id].remove(options) root.refresh(record)
record = @irecords[record.id].load(record) unless options.clear else
record.id or= record.cid record.id or= record.cid
@irecords[record.id] ?= record @irecords[record.id] = @irecords[record.cid] = record
@irecords[record.cid] ?= record @records.push(record)
@records.push(record) record
@refresh: (values, options = {}) -> @refresh: (values, options = {}) ->
@deleteAll() if options.clear @deleteAll() if options.clear
records = @fromJSON(values) records = @fromJSON(values)
records = [records] unless isArray(records) records = [records] unless isArray(records)
@addRecord(record, options) for record in records @addRecord(record) for record in records
@sort() @sort()
result = @cloneArray(records) result = @cloneArray(records)
@ -248,10 +249,13 @@ class Model extends Module
@toJSON: -> @toJSON: ->
@records @records
@beforeFromJSON: (objects) -> objects
@fromJSON: (objects) -> @fromJSON: (objects) ->
return unless objects return unless objects
if typeof objects is 'string' if typeof objects is 'string'
objects = JSON.parse(objects) objects = JSON.parse(objects)
objects = @beforeFromJSON(objects)
if isArray(objects) if isArray(objects)
for value in objects for value in objects
if value instanceof this if value instanceof this
@ -288,7 +292,7 @@ class Model extends Module
super super
if @constructor.uuid? and typeof @constructor.uuid is 'function' if @constructor.uuid? and typeof @constructor.uuid is 'function'
@cid = @constructor.uuid() @cid = @constructor.uuid()
@id = @cid unless @id @id = @cid unless @id
else else
@cid = atts?.cid or @constructor.uid('c-') @cid = atts?.cid or @constructor.uid('c-')
@load atts if atts @load atts if atts
@ -329,13 +333,13 @@ class Model extends Module
unless options.validate is false unless options.validate is false
error = @validate() error = @validate()
if error if error
@trigger('error', error) @trigger('error', this, error)
return false return false
@trigger('beforeSave', options) @trigger('beforeSave', this, options)
record = if @isNew() then @create(options) else @update(options) record = if @isNew() then @create(options) else @update(options)
@stripCloneAttrs() @stripCloneAttrs()
@trigger('save', options) @trigger('save', record, options)
record record
stripCloneAttrs: -> stripCloneAttrs: ->
@ -375,14 +379,13 @@ class Model extends Module
destroy: (options = {}) -> destroy: (options = {}) ->
options.clear ?= true options.clear ?= true
@trigger('beforeDestroy', options) @trigger('beforeDestroy', this, options)
@remove(options) @remove(options)
@destroyed = true @destroyed = true
# handle events # handle events
@trigger('destroy', options) @trigger('destroy', this, options)
@trigger('change', 'destroy', options) @trigger('change', this, 'destroy', options)
if @listeningTo @stopListening() if @listeningTo
@stopListening()
@unbind() @unbind()
this this
@ -392,7 +395,9 @@ class Model extends Module
delete atts.id delete atts.id
else else
atts.cid = @cid atts.cid = @cid
new @constructor(atts) record = new @constructor(atts)
@_callbacks and record._callbacks = @_callbacks unless newRecord
record
clone: -> clone: ->
createObject(this) createObject(this)
@ -403,12 +408,16 @@ class Model extends Module
@load(original.attributes()) @load(original.attributes())
original original
refresh: (data) -> refresh: (atts) ->
atts = @constructor.fromJSON(atts)
# ID change, need to do some shifting
if atts.id and @id isnt atts.id
@changeID(atts.id)
# go to the source and load attributes # go to the source and load attributes
root = @constructor.irecords[@id] @constructor.irecords[@id].load(atts)
root.load(data) @trigger('refresh', this)
@trigger('refresh') @trigger('change', this, 'refresh')
@ this
toJSON: -> toJSON: ->
@attributes() @attributes()
@ -438,7 +447,7 @@ class Model extends Module
# Private # Private
update: (options) -> update: (options) ->
@trigger('beforeUpdate', options) @trigger('beforeUpdate', this, options)
records = @constructor.irecords records = @constructor.irecords
records[@id].load @attributes() records[@id].load @attributes()
@ -446,61 +455,44 @@ class Model extends Module
@constructor.sort() @constructor.sort()
clone = records[@id].clone() clone = records[@id].clone()
clone.trigger('update', options) clone.trigger('update', clone, options)
clone.trigger('change', 'update', options) clone.trigger('change', clone, 'update', options)
clone clone
create: (options) -> create: (options) ->
@trigger('beforeCreate', options) @trigger('beforeCreate', this, options)
@id or= @cid @id or= @cid
record = @dup(false) record = @dup(false)
@constructor.addRecord(record) @constructor.addRecord(record)
@constructor.sort() @constructor.sort()
clone = record.clone() clone = record.clone()
clone.trigger('create', options) clone.trigger('create', clone, options)
clone.trigger('change', 'create', options) clone.trigger('change', clone, 'create', options)
clone clone
bind: (events, callback) -> bind: ->
@constructor.bind events, binder = (record) => record = @constructor.irecords[@id] or this
if record && @eql(record) Events.bind.apply record, arguments
callback.apply(this, arguments)
# create a wrapper function to be called with 'unbind' for each event
for singleEvent in events.split(' ')
do (singleEvent) =>
@constructor.bind "unbind", unbinder = (record, event, cb) =>
if record && @eql(record)
return if event and event isnt singleEvent
return if cb and cb isnt callback
@constructor.unbind(singleEvent, binder)
@constructor.unbind("unbind", unbinder)
this
one: (events, callback) -> one: ->
@bind events, handler = => record = @constructor.irecords[@id] or this
@unbind(events, handler) Events.one.apply record, arguments
callback.apply(this, arguments)
trigger: (args...) -> unbind: ->
args.splice(1, 0, this) record = @constructor.irecords[@id] or this
@constructor.trigger(args...) Events.unbind.apply record, arguments
listenTo: -> Events.listenTo.apply @, arguments trigger: ->
listenToOnce: -> Events.listenToOnce.apply @, arguments Events.trigger.apply this, arguments # fire off the instance event
stopListening: -> Events.stopListening.apply @, arguments return true if arguments[0] is 'refresh' # Don't trigger refresh events, because ... ?
@constructor.trigger arguments... # fire off the class event
unbind: (events, callback) -> Model::on = Model::bind
if arguments.length is 0
@trigger('unbind')
else if events
for event in events.split(' ')
@trigger('unbind', event, callback)
Model::on = Model::bind
Model::off = Model::unbind Model::off = Model::unbind
class Controller extends Module class Controller extends Module
@include Events @include Events
@include Log @include Log
@ -514,9 +506,8 @@ class Controller extends Module
for key, value of @options for key, value of @options
@[key] = value @[key] = value
@el = document.createElement(@tag) unless @el @el = document.createElement(@tag) unless @el
@el = $(@el) @el = $(@el)
@$el = @el
@el.addClass(@className) if @className @el.addClass(@className) if @className
@el.attr(@attributes) if @attributes @el.attr(@attributes) if @attributes
@ -542,7 +533,7 @@ class Controller extends Module
@unbind() @unbind()
@stopListening() @stopListening()
$: (selector) -> $(selector, @el) $: (selector) -> @el.find(selector)
delegateEvents: (events) -> delegateEvents: (events) ->
for key, method of events for key, method of events
@ -635,7 +626,7 @@ makeArray = (args) ->
Spine = @Spine = {} Spine = @Spine = {}
module?.exports = Spine module?.exports = Spine
Spine.version = '1.3.2' Spine.version = '1.4.1'
Spine.isArray = isArray Spine.isArray = isArray
Spine.isBlank = isBlank Spine.isBlank = isBlank
Spine.$ = $ Spine.$ = $