Updated to spine 1.3.1.
This commit is contained in:
parent
c1c8d89fd3
commit
f7cfc1a943
4 changed files with 144 additions and 85 deletions
|
@ -60,6 +60,12 @@ Ajax =
|
||||||
clearQueue: ->
|
clearQueue: ->
|
||||||
@queue []
|
@queue []
|
||||||
|
|
||||||
|
config:
|
||||||
|
loadMethod: 'GET'
|
||||||
|
updateMethod: 'PUT'
|
||||||
|
createMethod: 'POST'
|
||||||
|
destroyMethod: 'DELETE'
|
||||||
|
|
||||||
class Base
|
class Base
|
||||||
defaults:
|
defaults:
|
||||||
dataType: 'json'
|
dataType: 'json'
|
||||||
|
@ -118,7 +124,7 @@ class Collection extends Base
|
||||||
record = new @model(id: id)
|
record = new @model(id: id)
|
||||||
@ajaxQueue(
|
@ajaxQueue(
|
||||||
params, {
|
params, {
|
||||||
type: 'GET'
|
type: options.method or Ajax.config.loadMethod
|
||||||
url: options.url or Ajax.getURL(record)
|
url: options.url or Ajax.getURL(record)
|
||||||
parallel: options.parallel
|
parallel: options.parallel
|
||||||
}
|
}
|
||||||
|
@ -128,7 +134,7 @@ class Collection extends Base
|
||||||
all: (params, options = {}) ->
|
all: (params, options = {}) ->
|
||||||
@ajaxQueue(
|
@ajaxQueue(
|
||||||
params, {
|
params, {
|
||||||
type: 'GET'
|
type: options.method or Ajax.config.loadMethod
|
||||||
url: options.url or Ajax.getURL(@model)
|
url: options.url or Ajax.getURL(@model)
|
||||||
parallel: options.parallel
|
parallel: options.parallel
|
||||||
}
|
}
|
||||||
|
@ -159,7 +165,7 @@ class Singleton extends Base
|
||||||
reload: (params, options = {}) ->
|
reload: (params, options = {}) ->
|
||||||
@ajaxQueue(
|
@ajaxQueue(
|
||||||
params, {
|
params, {
|
||||||
type: 'GET'
|
type: options.method or Ajax.config.loadMethod
|
||||||
url: options.url
|
url: options.url
|
||||||
parallel: options.parallel
|
parallel: options.parallel
|
||||||
}, @record
|
}, @record
|
||||||
|
@ -169,7 +175,7 @@ class Singleton extends Base
|
||||||
create: (params, options = {}) ->
|
create: (params, options = {}) ->
|
||||||
@ajaxQueue(
|
@ajaxQueue(
|
||||||
params, {
|
params, {
|
||||||
type: 'POST'
|
type: options.method or Ajax.config.createMethod
|
||||||
contentType: 'application/json'
|
contentType: 'application/json'
|
||||||
data: @record.toJSON()
|
data: @record.toJSON()
|
||||||
url: options.url or Ajax.getCollectionURL(@record)
|
url: options.url or Ajax.getCollectionURL(@record)
|
||||||
|
@ -181,7 +187,7 @@ class Singleton extends Base
|
||||||
update: (params, options = {}) ->
|
update: (params, options = {}) ->
|
||||||
@ajaxQueue(
|
@ajaxQueue(
|
||||||
params, {
|
params, {
|
||||||
type: 'PUT'
|
type: options.method or Ajax.config.updateMethod
|
||||||
contentType: 'application/json'
|
contentType: 'application/json'
|
||||||
data: @record.toJSON()
|
data: @record.toJSON()
|
||||||
url: options.url
|
url: options.url
|
||||||
|
@ -193,7 +199,7 @@ class Singleton extends Base
|
||||||
destroy: (params, options = {}) ->
|
destroy: (params, options = {}) ->
|
||||||
@ajaxQueue(
|
@ajaxQueue(
|
||||||
params, {
|
params, {
|
||||||
type: 'DELETE'
|
type: options.method or Ajax.config.destroyMethod
|
||||||
url: options.url
|
url: options.url
|
||||||
parallel: options.parallel
|
parallel: options.parallel
|
||||||
}, @record
|
}, @record
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
Spine = @Spine or require('spine')
|
Spine = @Spine or require('spine')
|
||||||
$ = Spine.$
|
$ = Spine.$
|
||||||
|
|
||||||
|
|
||||||
class Spine.Manager extends Spine.Module
|
class Spine.Manager extends Spine.Module
|
||||||
@include Spine.Events
|
@include Spine.Events
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ class Spine.Manager extends Spine.Module
|
||||||
|
|
||||||
current.activate(args...) if current
|
current.activate(args...) if current
|
||||||
|
|
||||||
|
|
||||||
Spine.Controller.include
|
Spine.Controller.include
|
||||||
active: (args...) ->
|
active: (args...) ->
|
||||||
if typeof args[0] is 'function'
|
if typeof args[0] is 'function'
|
||||||
|
@ -45,11 +47,12 @@ Spine.Controller.include
|
||||||
|
|
||||||
activate: ->
|
activate: ->
|
||||||
@el.addClass('active')
|
@el.addClass('active')
|
||||||
@
|
this
|
||||||
|
|
||||||
deactivate: ->
|
deactivate: ->
|
||||||
@el.removeClass('active')
|
@el.removeClass('active')
|
||||||
@
|
this
|
||||||
|
|
||||||
|
|
||||||
class Spine.Stack extends Spine.Controller
|
class Spine.Stack extends Spine.Controller
|
||||||
controllers: {}
|
controllers: {}
|
||||||
|
@ -61,10 +64,11 @@ class Spine.Stack extends Spine.Controller
|
||||||
super
|
super
|
||||||
|
|
||||||
@manager = new Spine.Manager
|
@manager = new Spine.Manager
|
||||||
|
@router = Spine.Route?.create()
|
||||||
|
|
||||||
for key, value of @controllers
|
for key, value of @controllers
|
||||||
throw Error "'@#{ key }' already assigned - choose a different name" if @[key]?
|
throw Error "'@#{ key }' already assigned" if @[key]?
|
||||||
@[key] = new value(stack: @)
|
@[key] = new value(stack: this)
|
||||||
@add(@[key])
|
@add(@[key])
|
||||||
|
|
||||||
for key, value of @routes
|
for key, value of @routes
|
||||||
|
@ -79,5 +83,10 @@ class Spine.Stack extends Spine.Controller
|
||||||
@manager.add(controller)
|
@manager.add(controller)
|
||||||
@append(controller)
|
@append(controller)
|
||||||
|
|
||||||
|
release: =>
|
||||||
|
@router?.destroy()
|
||||||
|
super
|
||||||
|
|
||||||
|
|
||||||
module?.exports = Spine.Manager
|
module?.exports = Spine.Manager
|
||||||
module?.exports.Stack = Spine.Stack
|
module?.exports.Stack = Spine.Stack
|
||||||
|
|
|
@ -6,13 +6,47 @@ namedParam = /:([\w\d]+)/g
|
||||||
splatParam = /\*([\w\d]+)/g
|
splatParam = /\*([\w\d]+)/g
|
||||||
escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g
|
escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g
|
||||||
|
|
||||||
class Spine.Route extends Spine.Module
|
|
||||||
|
class Path extends Spine.Module
|
||||||
|
|
||||||
|
constructor: (@path, @callback) ->
|
||||||
|
@names = []
|
||||||
|
|
||||||
|
if typeof path is 'string'
|
||||||
|
namedParam.lastIndex = 0
|
||||||
|
while (match = namedParam.exec(path)) != null
|
||||||
|
@names.push(match[1])
|
||||||
|
|
||||||
|
splatParam.lastIndex = 0
|
||||||
|
while (match = splatParam.exec(path)) != null
|
||||||
|
@names.push(match[1])
|
||||||
|
|
||||||
|
path = path.replace(escapeRegExp, '\\$&')
|
||||||
|
.replace(namedParam, '([^\/]*)')
|
||||||
|
.replace(splatParam, '(.*?)')
|
||||||
|
|
||||||
|
@route = new RegExp("^#{path}$")
|
||||||
|
else
|
||||||
|
@route = path
|
||||||
|
|
||||||
|
match: (path, options = {}) ->
|
||||||
|
return false unless match = @route.exec(path)
|
||||||
|
options.match = match
|
||||||
|
params = match.slice(1)
|
||||||
|
|
||||||
|
if @names.length
|
||||||
|
for param, i in params
|
||||||
|
options[@names[i]] = param
|
||||||
|
|
||||||
|
Route.trigger('before', this)
|
||||||
|
@callback.call(null, options) isnt false
|
||||||
|
|
||||||
|
|
||||||
|
class Route extends Spine.Module
|
||||||
@extend Spine.Events
|
@extend Spine.Events
|
||||||
|
|
||||||
@historySupport: window.history?.pushState?
|
@historySupport: window.history?.pushState?
|
||||||
|
|
||||||
@routes: []
|
|
||||||
|
|
||||||
@options:
|
@options:
|
||||||
trigger: true
|
trigger: true
|
||||||
history: false
|
history: false
|
||||||
|
@ -20,16 +54,12 @@ class Spine.Route extends Spine.Module
|
||||||
replace: false
|
replace: false
|
||||||
redirect: false
|
redirect: false
|
||||||
|
|
||||||
@add: (path, callback) ->
|
@routers: []
|
||||||
if (typeof path is 'object' and path not instanceof RegExp)
|
|
||||||
@add(key, value) for key, value of path
|
|
||||||
else
|
|
||||||
@routes.push(new @(path, callback))
|
|
||||||
|
|
||||||
@setup: (options = {}) ->
|
@setup: (options = {}) ->
|
||||||
@options = $.extend({}, @options, options)
|
@options = $.extend({}, @options, options)
|
||||||
|
|
||||||
if (@options.history)
|
if @options.history
|
||||||
@history = @historySupport and @options.history
|
@history = @historySupport and @options.history
|
||||||
|
|
||||||
return if @options.shim
|
return if @options.shim
|
||||||
|
@ -65,11 +95,11 @@ class Spine.Route extends Spine.Module
|
||||||
|
|
||||||
@trigger('navigate', @path)
|
@trigger('navigate', @path)
|
||||||
|
|
||||||
route = @matchRoute(@path, options) if options.trigger
|
routes = @matchRoutes(@path, options) if options.trigger
|
||||||
|
|
||||||
return if options.shim
|
return if options.shim
|
||||||
|
|
||||||
if !route
|
unless routes.length
|
||||||
if typeof options.redirect is 'function'
|
if typeof options.redirect is 'function'
|
||||||
return options.redirect.apply this, [@path, options]
|
return options.redirect.apply this, [@path, options]
|
||||||
else
|
else
|
||||||
|
@ -83,6 +113,25 @@ class Spine.Route extends Spine.Module
|
||||||
else
|
else
|
||||||
window.location.hash = @path
|
window.location.hash = @path
|
||||||
|
|
||||||
|
@create: ->
|
||||||
|
router = new this
|
||||||
|
@routers.push router
|
||||||
|
router
|
||||||
|
|
||||||
|
@add: (path, callback) ->
|
||||||
|
#@router ?= new this
|
||||||
|
@router.add path, callback
|
||||||
|
|
||||||
|
add: (path, callback) ->
|
||||||
|
if typeof path is 'object' and path not instanceof RegExp
|
||||||
|
@add(key, value) for key, value of path
|
||||||
|
else
|
||||||
|
@routes.push(new Path(path, callback))
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
@routes.length = 0
|
||||||
|
@constructor.routers = (r for r in @constructor.routers when r isnt this)
|
||||||
|
|
||||||
# Private
|
# Private
|
||||||
|
|
||||||
@getPath: ->
|
@getPath: ->
|
||||||
|
@ -97,57 +146,42 @@ class Spine.Route extends Spine.Module
|
||||||
@getHost: ->
|
@getHost: ->
|
||||||
"#{window.location.protocol}//#{window.location.host}"
|
"#{window.location.protocol}//#{window.location.host}"
|
||||||
|
|
||||||
@change: ->
|
@change: =>
|
||||||
path = @getPath()
|
path = @getPath()
|
||||||
return if path is @path
|
return if path is @path
|
||||||
@path = path
|
@path = path
|
||||||
@matchRoute(@path)
|
@matchRoutes(@path)
|
||||||
|
|
||||||
@matchRoute: (path, options) ->
|
@matchRoutes: (path, options)->
|
||||||
for route in @routes when route.match(path, options)
|
matches = []
|
||||||
@trigger('change', route, path)
|
for router in @routers.concat [@router]
|
||||||
return route
|
match = router.matchRoute path, options
|
||||||
|
matches.push match if match
|
||||||
|
@trigger('change', matches, path) if matches.length
|
||||||
|
matches
|
||||||
|
|
||||||
@redirect: (path) ->
|
@redirect: (path) ->
|
||||||
window.location = path
|
window.location = path
|
||||||
|
|
||||||
constructor: (@path, @callback) ->
|
constructor: ->
|
||||||
@names = []
|
@routes = []
|
||||||
|
|
||||||
if typeof path is 'string'
|
matchRoute: (path, options) ->
|
||||||
namedParam.lastIndex = 0
|
for route in @routes when route.match(path, options)
|
||||||
while (match = namedParam.exec(path)) != null
|
return route
|
||||||
@names.push(match[1])
|
|
||||||
|
|
||||||
splatParam.lastIndex = 0
|
trigger: (args...) ->
|
||||||
while (match = splatParam.exec(path)) != null
|
args.splice(1, 0, this)
|
||||||
@names.push(match[1])
|
@constructor.trigger(args...)
|
||||||
|
|
||||||
path = path.replace(escapeRegExp, '\\$&')
|
Route.router = new Route
|
||||||
.replace(namedParam, '([^\/]*)')
|
|
||||||
.replace(splatParam, '(.*?)')
|
|
||||||
|
|
||||||
@route = new RegExp("^#{path}$")
|
|
||||||
else
|
|
||||||
@route = path
|
|
||||||
|
|
||||||
match: (path, options = {}) ->
|
|
||||||
match = @route.exec(path)
|
|
||||||
return false unless match
|
|
||||||
options.match = match
|
|
||||||
params = match.slice(1)
|
|
||||||
|
|
||||||
if @names.length
|
|
||||||
for param, i in params
|
|
||||||
options[@names[i]] = param
|
|
||||||
@.constructor.trigger('before', @)
|
|
||||||
@callback.call(null, options) isnt false
|
|
||||||
|
|
||||||
# Coffee-script bug
|
|
||||||
Spine.Route.change = Spine.Route.proxy(Spine.Route.change)
|
|
||||||
|
|
||||||
Spine.Controller.include
|
Spine.Controller.include
|
||||||
route: (path, callback) ->
|
route: (path, callback) ->
|
||||||
|
if @router instanceof Spine.Route
|
||||||
|
@router.add(path, @proxy(callback))
|
||||||
|
else
|
||||||
Spine.Route.add(path, @proxy(callback))
|
Spine.Route.add(path, @proxy(callback))
|
||||||
|
|
||||||
routes: (routes) ->
|
routes: (routes) ->
|
||||||
|
@ -156,4 +190,6 @@ Spine.Controller.include
|
||||||
navigate: ->
|
navigate: ->
|
||||||
Spine.Route.navigate.apply(Spine.Route, arguments)
|
Spine.Route.navigate.apply(Spine.Route, arguments)
|
||||||
|
|
||||||
module?.exports = Spine.Route
|
Route.Path = Path
|
||||||
|
Spine.Route = Route
|
||||||
|
module?.exports = Route
|
||||||
|
|
|
@ -157,21 +157,21 @@ class Model extends Module
|
||||||
@exists: (id) ->
|
@exists: (id) ->
|
||||||
return if @irecords[id] then true else false
|
return if @irecords[id] then true else false
|
||||||
|
|
||||||
@addRecord: (record) ->
|
@addRecord: (record, options = {}) ->
|
||||||
if record.id and @irecords[record.id]
|
if record.id and @irecords[record.id]
|
||||||
@irecords[record.id].remove()
|
@irecords[record.id].remove(options)
|
||||||
|
record = @irecords[record.id].load(record) unless options.clear
|
||||||
record.id or= record.cid
|
record.id or= record.cid
|
||||||
|
@irecords[record.id] ?= record
|
||||||
|
@irecords[record.cid] ?= record
|
||||||
@records.push(record)
|
@records.push(record)
|
||||||
@irecords[record.id] = record
|
|
||||||
@irecords[record.cid] = 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) for record in records
|
@addRecord(record, options) for record in records
|
||||||
@sort()
|
@sort()
|
||||||
|
|
||||||
result = @cloneArray(records)
|
result = @cloneArray(records)
|
||||||
|
@ -252,8 +252,13 @@ class Model extends Module
|
||||||
if typeof objects is 'string'
|
if typeof objects is 'string'
|
||||||
objects = JSON.parse(objects)
|
objects = JSON.parse(objects)
|
||||||
if isArray(objects)
|
if isArray(objects)
|
||||||
(new @(value) for value in objects)
|
for value in objects
|
||||||
|
if value instanceof this
|
||||||
|
value
|
||||||
else
|
else
|
||||||
|
new @(value)
|
||||||
|
else
|
||||||
|
return objects if objects instanceof this
|
||||||
new @(objects)
|
new @(objects)
|
||||||
|
|
||||||
@fromForm: ->
|
@fromForm: ->
|
||||||
|
@ -298,7 +303,8 @@ class Model extends Module
|
||||||
load: (atts) ->
|
load: (atts) ->
|
||||||
if atts.id then @id = atts.id
|
if atts.id then @id = atts.id
|
||||||
for key, value of atts
|
for key, value of atts
|
||||||
if atts.hasOwnProperty(key) and typeof @[key] is 'function'
|
if typeof @[key] is 'function'
|
||||||
|
continue if typeof value is 'function'
|
||||||
@[key](value)
|
@[key](value)
|
||||||
else
|
else
|
||||||
@[key] = value
|
@[key] = value
|
||||||
|
@ -354,20 +360,22 @@ class Model extends Module
|
||||||
@id = id
|
@id = id
|
||||||
@save()
|
@save()
|
||||||
|
|
||||||
remove: ->
|
remove: (options = {}) ->
|
||||||
# Remove record from model
|
# Remove record from model
|
||||||
records = @constructor.records.slice(0)
|
records = @constructor.records.slice(0)
|
||||||
for record, i in records when @eql(record)
|
for record, i in records when @eql(record)
|
||||||
records.splice(i, 1)
|
records.splice(i, 1)
|
||||||
break
|
break
|
||||||
@constructor.records = records
|
@constructor.records = records
|
||||||
# Remove the ID and CID
|
if options.clear
|
||||||
|
# Remove the ID and CID indexes
|
||||||
delete @constructor.irecords[@id]
|
delete @constructor.irecords[@id]
|
||||||
delete @constructor.irecords[@cid]
|
delete @constructor.irecords[@cid]
|
||||||
|
|
||||||
destroy: (options = {}) ->
|
destroy: (options = {}) ->
|
||||||
|
options.clear ?= true
|
||||||
@trigger('beforeDestroy', options)
|
@trigger('beforeDestroy', options)
|
||||||
@remove()
|
@remove(options)
|
||||||
@destroyed = true
|
@destroyed = true
|
||||||
# handle events
|
# handle events
|
||||||
@trigger('destroy', options)
|
@trigger('destroy', options)
|
||||||
|
@ -626,7 +634,7 @@ makeArray = (args) ->
|
||||||
Spine = @Spine = {}
|
Spine = @Spine = {}
|
||||||
module?.exports = Spine
|
module?.exports = Spine
|
||||||
|
|
||||||
Spine.version = '1.3.0'
|
Spine.version = '1.3.1'
|
||||||
Spine.isArray = isArray
|
Spine.isArray = isArray
|
||||||
Spine.isBlank = isBlank
|
Spine.isBlank = isBlank
|
||||||
Spine.$ = $
|
Spine.$ = $
|
||||||
|
|
Loading…
Reference in a new issue