Javascript 如何在Backbone.js中处理关联更改?
假设我有一个包含两个集合的应用程序:Javascript 如何在Backbone.js中处理关联更改?,javascript,backbone.js,Javascript,Backbone.js,假设我有一个包含两个集合的应用程序:用户和任务。它们之间存在多对多的关联——一个任务可以与任意数量的用户关联,反之亦然。处理新协会的最佳方式是什么 一种方法是为每个用户分配新的任务集合: Users = Backbone.Model.extend({ this.tasks = new Tasks; ... }); 然后使用模型(或副本)作为输入执行this.tasks.create() 问题是任务应该已经有了id。如果模型有id,主干网希望进行更新。因此,与此不同的是: { use
用户
和任务
。它们之间存在多对多的关联——一个任务可以与任意数量的用户关联,反之亦然。处理新协会的最佳方式是什么
一种方法是为每个用户分配新的任务集合:
Users = Backbone.Model.extend({
this.tasks = new Tasks;
...
});
然后使用模型(或副本)作为输入执行this.tasks.create()
问题是任务应该已经有了id。如果模型有id,主干网希望进行更新。因此,与此不同的是:
{
username: "jsmith"
name: "Joe Smith"
tasks: [5, 15, 256]
}
// 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();
}
})
POST/users/156/任务
你会得到这样的结果:
{
username: "jsmith"
name: "Joe Smith"
tasks: [5, 15, 256]
}
// 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();
}
})
PUT/users/156/tasks/15
这不是你想要的。您只需重新定义该模型的isNew()
函数,就可以让主干网发布文章,但这看起来像是一个黑客行为
另一种方法是在两端维护ID列表。例如,用户
模型JSON可以如下所示:
{
username: "jsmith"
name: "Joe Smith"
tasks: [5, 15, 256]
}
// 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();
}
})
只需从您想要添加的模型中获取ID,然后对用户进行一次PUT
这里的问题是,更多的数据是通过线路发送的,而具体的更改没有表示出来。服务器必须做更多的工作来过滤模型,找出发生了什么变化,并根据需要添加/删除关联(这里的后端是SQL,所以我们不只是处理嵌入式任务列表或任何东西)。请求所需的特定关联更改似乎要好得多
那么,哪种方法似乎最好?还有其他我没有考虑的选择吗
(注意:我希望避免像主干关系这样的主干扩展)在这些情况下,我创建了一个特定的路由来处理关系,而不是它们自身的对象,例如:
POST /users/156/tasks_relations
使用这种方法,我们更接近于纯粹的RESTAPI,因为事实上我们所做的不是创建(POST)一个任务
,而是创建(POST)一个任务关系
在主干网中,我还有一个特定的任务关系
模型来表示这种关系:
// 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;
}
});
因此,在用户
中,我们可以向服务器发送一个新的任务关系
,如下所示:
{
username: "jsmith"
name: "Joe Smith"
tasks: [5, 15, 256]
}
// 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\u id
参数并执行其业务。您可以保持事物无状态,只需使用options.data散列获取每次使用的任务集合。我不确定我是否理解为什么在创建任务时任务会有id。这一切都取决于您使用它做什么,取决于您绑定到的事件,如果每个用户都有一个集合作为子参数,那么在某些事件上执行的代码可能会对性能造成影响,尽管我没有关于这方面的可靠数据。我想知道为什么要选择避免主干关系型?@Uzi任务有ID,在这个示例所基于的应用程序中,因为它们都被持久化到服务器上了。@Sander主干关系型任务似乎增加了相当多的复杂性和魔力;我希望避免给其他开发者(和我自己)带来理解该应用程序的另一个障碍。