如何在Backbone.js v0.5中构建深层嵌套模型

Ali*_*ehi 6 backbone.js

假设每个A具有0或更多B并且每个B具有0个或更多个C项.如何在Backbone.js中呈现这种关系(v0.5).我想要像/ A/a/B/b/C/c这样的网址.以下代码在coffeescript中.我很困惑,如何在以下代码中设置url变量.

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   
Run Code Online (Sandbox Code Playgroud)

bra*_*ing 7

我不会创建嵌套的URL,除非你真的有一个很好的案例.每个资源都可以由资源名称和id定义.对象之间的关系是内部的.

http://foo.com/a/:id.json
http://foo.com/b/:id.json
http://foo.com/c/:id.json
Run Code Online (Sandbox Code Playgroud)

据说很多服务器提取嵌套对象并不是很理想.你最好有一个返回嵌套json的资源

http://foo.com/a/:id.json
Run Code Online (Sandbox Code Playgroud)

例如,我从服务器返回的数据看起来像

{
  "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"
  }
}
Run Code Online (Sandbox Code Playgroud)

子节点由自定义控制器组装,该控制器获取单个db记录并生成数据树.

但是你现在遇到了麻烦,因为backbone.js本身只支持扁平结构.我对基本的Backbone.Model进行了一些修改,以支持处理树状结构.

如果它对你有用,我会把它贴在这里.

#= 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
Run Code Online (Sandbox Code Playgroud)

你可以像使用它一样

model = new RailsModel
model.url = "/data"
model.fetch()
model.get('excercise/duration')
model.set_field('excercise/duration', 25)
Run Code Online (Sandbox Code Playgroud)

最后一行将触发事件"更改:运动/持续时间"