2011-07-05 30 views
6

Giả sử mỗi A có từ 0 trở lên B và mỗi B có từ 0 mục trở lên. Làm thế nào người ta sẽ trình bày mối quan hệ này trong Backbone.js (v0.5). Tôi muốn có các url như/A/a/B/b/C/c. Các mã sau đây là trong coffeescript. Tôi bối rối, làm thế nào để thiết lập các biến url trong đoạn mã sau.Cách xây dựng các mô hình lồng nhau sâu trong Backbone.js v0.5

class As extends Backbone.Collection 
    url: "/A" 
    model: A 

class A extends Backbone.Model 
    initialize: -> 
    @Bs = new Bs() 
    @[email protected] 
    @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/ 
    @[email protected] 

class Cs extends Backbone.Collection 
    model: C 

class C extends Backbone.Model 
    url: #?? url => /A/a/B/b/C/c 

Trả lời

7

Tôi sẽ không tạo URL lồng nhau trừ khi bạn thực sự có một trường hợp tốt cho nó. Mỗi tài nguyên có thể được xác định bởi một tên tài nguyên và một id. Mối quan hệ giữa các đối tượng là nội bộ.

http://foo.com/a/:id.json 
http://foo.com/b/:id.json 
http://foo.com/c/:id.json 

Điều đó đang được nói nhiều lần truy cập vào máy chủ để kéo ra các đối tượng lồng nhau không thực sự lý tưởng. Bạn đang có tốt hơn một nguồn tài nguyên duy nhất mà trả về lồng nhau json

http://foo.com/a/:id.json 

Ví dụ dữ liệu tôi có được trở lại từ máy chủ của tôi trông giống như

{ 
    "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" 
    } 
} 

Các nút phụ được lắp ráp bởi một bộ điều khiển tùy chỉnh mà có cá nhân bản ghi db và tạo một cây dữ liệu.

Tuy nhiên bạn hiện đang gặp sự cố vì backbone.js chỉ hỗ trợ cấu trúc phẳng. Tôi đã thực hiện một số sửa đổi cho Backbone.Model cơ bản để hỗ trợ xử lý cây như cấu trúc.

Tôi sẽ dán nó ở đây nếu nó có thể được sử dụng cho bạn.

#= 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 

Bạn có thể sử dụng nó như

model = new RailsModel 
model.url = "/data" 
model.fetch() 
model.get('excercise/duration') 
model.set_field('excercise/duration', 25) 

Dòng cuối cùng sẽ kích hoạt một sự kiện "thay đổi: excercise/thời gian"

Các vấn đề liên quan