如何在Backbone.js中处理关联更改?

时间:2012-03-07 04:14:52

标签: javascript backbone.js

假设我有一个包含两个集合的应用:UsersTasks。这些之间存在多对多关联 - 任务可以与任意数量的用户相关联,反之亦然。处理新协会的最佳方式是什么?

一种方法是为每个用户分配一组新的任务:

Users = Backbone.Model.extend({
  this.tasks = new Tasks;
  ...
});

然后以模型(或副本)作为输入进行this.tasks.create()

这个问题是任务应该已经有了id。如果模型具有id,Backbone希望进行更新。所以不是这样的事情:

POST /users/156/tasks

你得到这样的东西:

PUT /users/156/tasks/15

这不是你想要的。您可以重新定义该模型的isNew()函数以使Backbone执行POST,但这看起来像是一个黑客。

另一种方法是在任一端维护一个id列表。例如,User模型JSON可能如下所示:

{
  username: "jsmith"
  name: "Joe Smith"
  tasks: [5, 15, 256]
}

只需从您要添加的模型中获取ID,然后对用户执行PUT。

此处的问题是通过线路发送更多数据,并且未表示特定更改。服务器必须做更多的工作来过滤模型,弄清楚改变了什么,并根据需要添加/删除关联(后端这里是SQL,所以我们不只是处理嵌入式任务列表或任何东西)。请求更新所需的特定关联似乎要好得多。

那么哪种方法最好?还有其他我不考虑的选择吗?

(注意:我想避免像Backbone-relational这样的Backbone扩展)

1 个答案:

答案 0 :(得分:1)

对于这些情况,我创建了一个处理关系的特定路线,而不是他们自己的对象,例如:

POST /users/156/tasks_relations

使用这种方法我们更接近纯REST API,因为实际上我们正在做的不是创建(POST)一个Task而是创建(POST) a TaskRelation

在Backbone中,我还有一个代表关系的特定TaskRelation模型:

// code simplified and not tested
var TaskRelation = Backbone.Model.extend({
  urlRoot: function(){
    return this.user.url + "/tasks_relations";
  },

  initialize: function( opts ){
    this.user = opts.user;
  }
});

所以在User我们可以像这样向服务器发送新的TaskRelation

// code simplified and not tested
var User = Backbone.Model.extend({
  addTask: function( task ){
    var task_relation = new TaskRelation({ user: this, task_id: id });
    task_relation.save();
  }
})

服务器将采用task_id参数并开展业务。