4

对不起,如果这有点令人费解......我还在学习 Backbone.js......

加载和保存具有子模型的主干模型的正确方法是什么?(我什至应该有子模型吗?)

例如,(请原谅咖啡脚本),如果我有类似的东西:

class Address extends Backbone.Model
  urlRoot: '/api/v1/address/'
  url: -> return @urlRoot+@id+'/?format=json'
  defaults: {'city': '', 'state': ''}

class Person extends Backbone.Model
  urlRoot: '/api/v1/person/'
  url: -> return @urlRoot+@id+'/?format=json'
  defaults: { name: 'Anon', address: new Address }

... and then I do this ...

dude = new Person
dude.set('id',101)
dude.fetch()
// Response returns {name: 'The Dude', address: '/api/v1/address/1998/'}
// And now, dude.get('address') is '/api/v1/address/1998' and no Address object

where = new Address
where.set('id',1998)
where.fetch()
// Response returns {city: 'Venice', state; 'CA'}

我想说的是 dude.fetch() 并让它同时获取这个家伙和他的地址,当我调用 Backbone.sync('update',dude) 时,我想保存这个家伙和他的地址。如何?

在后端,我使用tastepie 为一些SQLAlchemy 表(不是Django 的ORM)构建我的api,所以我有一个资源用于我的Person 表和Address 表:

class AddressResource(SQLAlchemyResource):
    class Meta:
        resource_name = 'address'
        object_class = AddressSQLAlchemyORMClass

class PersonResource(SQLAlchemyResource):
    address = ForeignKey(AddressResource, 'address')
    class Meta:
        resource_name = 'person'
        object_class = PersonSQLAlchemyORMClass

Tastypie 的ForeignKey函数创建一个映射,将URL返回到相关地址。

我尝试重载 Dude.parse() 函数来调用 Address() 的 fetch,但它不起作用并且感觉不对,并且引发了各种各样的问题:

  1. 我应该修改我的美味响应以将地址包含为嵌套对象吗?
  2. 如果我更改为嵌套对象,我应该使用主干关系,如未创建主干关系相关模型的问题,还是过度杀伤?
  3. 我应该重载 parse()或 fetch() 函数还是创建自己的主干.Sync() 以获取响应然后手动执行此操作?
  4. 既然是一对一的,我是否应该只拥有一个模型而不是子模型,然后在一个请求中将信息一起发送回?

有这样做的标准方法吗?

4

1 回答 1

3

使用 Tastypie,您可以通过在 ForeignKey 定义中指定full=True将响应更改为嵌套对象而不是链接:

class PersonResource(SQLAlchemyResource):
    address = ForeignKey(AddressResource, 'address', full=True)

这将返回地址对象以及人员。

接下来,我仍然不知道这是否是最好的方法,但我将我的子模型移出属性,并重载 parse() 来设置它,并重载 update() 来保存它,比如:

class Person extends Backbone.Model
  address: new Address
  urlRoot: '/api/v1/person/'
  url: -> return @urlRoot+@id+'/?format=json'
  defaults: { name: 'Anon'}

  parse: (response) ->
     addressResp = response.address || {}
     addressAttr = @address.parse(addressResp)
     @address.set(addressAttr)
     return response

  update: (options) ->
     @set('address',@address.toJSON())
     Backbone.sync 'update', @, options

在此示例中,我可以将地址添加回属性并使用 set/get 对其进行管理,但是在我自己的环境中,我创建了一个备用 toJSON 函数以将 json 发布到服务器,但找不到将 json 设置为对象而不将其从集合更改为 json 响应的好方法。

于 2012-07-16T13:28:33.180 回答