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