Assuming each A has 0 or more B and each B has 0 or more C items. How would one present this relationship in Backbone.js (v0.5). I would like to have urls like /A/a/B/b/C/c. The following code is in coffeescript. I am confused, how to set the url variables in the follow code.
class As extends Backbone.Collection
url: "/A"
model: A
class A extends Backbone.Model
initialize: ->
@Bs = new Bs()
@Bs.parent=@
@Bs.url="/A/#{@id}"
class Bs extends Backbone.Collection
model: B
class B extends Backbone.Model
initialize: ->
@Cs = new Cs()
@Cs.url = ??? # => /A/a/B/b/C/
@Cs.parent=@
class Cs extends Backbone.Collection
model: C
class C extends Backbone.Model
url: #?? url => /A/a/B/b/C/c
I would not create nested URL's unless you really have a good case for it. Each resource can be defined by a resource name and an id. The relationship between the objects is internal.
http://foo.com/a/:id.json
http://foo.com/b/:id.json
http://foo.com/c/:id.json
That being said lots of hits to the server to pull out nested objects is not really ideal. You are better having a single resource that returns nested json
http://foo.com/a/:id.json
For example the data I get back from my server looks like
{
"id": 372,
"context": "office_work",
"date_of_entry": "2011-7-05 15:22:00",
"blood_glucose_measurement": 98,
"food": {
"exchanges": "98",
"list": "burger fries"
},
"exercise": {
"duration": "28",
"list": "running shopping"
}
}
The sub nodes are assembled by a custom controller that takes the individual db records and makes a tree of data.
However you are now in trouble because backbone.js natively only supports flat structures. I've made some modifications to the basic Backbone.Model to support processing tree like structures.
I'll paste it here if it might be of use to you.
#= require jquery
#= require underscore
#= require backbone
#
class RailsModel extends Backbone.Model
initialize: (attributes) ->
data = {}
for k,v of @attributes
if v.constructor.name == "Object"
data[k] = new RailsModel(v)
@set data, {silent: true}
get: (field)->
val = @
first = true
for p in field.split('/')
if first
val = super(p)
else
# This allows returning *undefined* rather
# than an exception if the parent of a deeply
# nested node does not exist.
val = if val? then val.get(p) else undefined
first = false
val
# Allow heirarchical setting of objects
#
# Example
#
# model.set_field('root/child', 10)
#
# Will create the path if it does not exist
set_field: (field, value, silent=false)->
path = field.split('/')
node = undefined
val = @
for p in field.split('/')
node = val
val = node.get(p)
if not val?
data = {}
val = new RailsModel
data[p] = val
node.set data
data = {}
data[p] = value
node.set data
if not silent and /\//.test(field)
@trigger("change:#{field}", @model, value)
@trigger("change", @model)
window.RailsModel = RailsModel
You can use it like
model = new RailsModel
model.url = "/data"
model.fetch()
model.get('excercise/duration')
model.set_field('excercise/duration', 25)
The last line will trigger an event "change:excercise/duration"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With