Permalink
Browse files

load data on model reference for async use

  • Loading branch information...
1 parent e70f7bd commit 84c7855d7ae36d1df1d5155cc23e117531e07ad4 @collin committed Apr 11, 2012
Showing with 40 additions and 24 deletions.
  1. +18 −9 lib/alpha_simprini/core/model.coffee
  2. +18 −13 lib/alpha_simprini/core/model/rest.coffee
  3. +4 −2 test/core/model/rest.coffee
View
27 lib/alpha_simprini/core/model.coffee
@@ -9,19 +9,28 @@ AS.Model = AS.Object.extend ({def, include}) ->
def initialize: (attributes={}) ->
@model = this
- @id = attributes.id ? AS.uniq()
- @idRef = "#{@id}-#{@constructor.path()}"
- @cid = @idRef or uniqueId("c")
- delete attributes.id
-
- AS.All.byCid[@cid] = AS.All.byId[@id] = AS.All.byIdRef[@idRef] = this
-
@set(attributes)
def set: (attributes) ->
for key, value of attributes
- # assert @[key].set
- @[key].set(value)
+ if key is "id"
+ @setId(value)
+ else
+ # assert @[key].set
+ @[key].set(value)
+
+ def setId: (id=AS.uniq()) ->
+ if @id
+ delete AS.All.byId[@id]
+ delete AS.All.byIdRef["#{@id}-#{@constructor.path()}"]
+
+ @id = id
+ @idRef = "#{@id}-#{@constructor.path()}"
+ @cid = @idRef or uniqueId("c")
+ AS.All.byCid[@cid] = AS.All.byId[@id] = AS.All.byIdRef[@idRef] = this
+
+ # Don't trigger 'change', this must be specifically listened for.
+ @trigger("change:id")
def destroy: ->
@trigger("destroy")
View
31 lib/alpha_simprini/core/model/rest.coffee
@@ -1,6 +1,6 @@
AS = require "alpha_simprini"
{camelize, underscore, pluralize} = require "fleck"
-isArray = require "underscore"
+_ = require "underscore"
$ = require "jquery"
convertKeys = (object) ->
@@ -34,29 +34,32 @@ AS.Model.REST = AS.Module.extend ({delegate, include, def, defs}) ->
unless model = AS.All.byId[id]
model = @new()
callback ?= model.didLoad
- @readOne id, _.bind(callback, model)
+ @readOne id, callback
return model
- defs readOne: (id) ->
- $.get
+ def didLoad: (data) ->
+ @loadData(data)
+
+ defs readOne: (id, callback=@loadData) ->
+ $.ajax
url: @resourceURL(id)
dataType: 'json'
- success: _.bind(@loadData, this)
+ success: _.bind(callback, this)
error: =>
console.error "readone error"
console.error(this, arguments)
defs mappings: ->
mappings = {}
for klass in @appendedTo
- mappings[pluralize klass.rootKey()] = klass
+ mappings[pluralize(camelize(klass.rootKey()))] = klass
mappings
- defs loadData: (data) ->
+ def loadData: (data) ->
references = AS.Map.new()
- root = @rootKey()
+ root = @constructor.rootKey()
# TODO: implement runtime assertions
# assert data[root], "loaded data for, but JSON had no data at rootKey: #{root}"
@@ -65,17 +68,18 @@ AS.Model.REST = AS.Module.extend ({delegate, include, def, defs}) ->
modelData = convertKeys(modelData)
[modelData, ids] = extractIds(modelData)
- model = @new(modelData)
- references.set(model, ids)
+ @set(modelData)
- for key, embeds of data
+ references.set(this, ids)
+
+ for key, embeds of convertKeys(data)
continue if key is root
# assert AS.Model.REST.mappings[key], "sideload data provided for #{key}, but no mapping exists in AS.Model.REST.mappings"
- @mappings()[key].sideloadData(embed, references) for embed in embeds
+ @constructor.mappings()[key].sideloadData(embed, references) for embed in embeds
references.each (model, ids) -> model.resolveReferences(ids)
- return model
+ return this
defs sideloadData: (modelData, references) ->
modelData = convertKeys(modelData)
@@ -89,6 +93,7 @@ AS.Model.REST = AS.Module.extend ({delegate, include, def, defs}) ->
continue unless references
relationKey = key.replace(/Id/, '')
+ return if @[relationKey + "Type"] # polymorphic!
path = @[relationKey].model().path()
if references.length is undefined
View
6 test/core/model/rest.coffee
@@ -58,14 +58,16 @@ sideLoading =
exports.REST =
"loads a model from a simple JSON response": (test) ->
- model = Rested.loadData(plain)
+ model = Rested.new()
+ model.loadData(plain)
test.equal "value", model.field.get()
test.equal null, model.owner.get()
test.equal 0, model.relations.backingCollection.length
test.done()
"loads a model from a JSON respons w/sideLoading": (test) ->
- model = Rested.loadData(sideLoading)
+ model = Rested.new()
+ model.loadData(sideLoading)
test.equal "packed", model.field.get()
test.ok sideloaded = AS.All.byIdRef["1-NS.SimpleRest"]
test.equal "first", sideloaded.field.get()

0 comments on commit 84c7855

Please sign in to comment.