我被困在如何设计我的主干.js关于我的模型关系的应用程序上。
如果我有一个事件模型,它有几个关系,比如说一个用户模型可以有很多事件,而事件模型反过来可以有很多评论和参与。一个用户可以有多个评论,参与可以有一个用户和一个事件。哇,真是一团糟!
Event has many Comments
Event has many Participations
Event has one User
User has many Events
User has many Participations
User has many Comments
Comment has one Event
Comment has one User
Participation has one User
Participation has one Event
好的,所以我的想法是在用户加载页面时加载事件列表,当用户单击事件加载有关该事件的其余信息(评论、参与和用户)时。
所以问题是,我是否应该使用某种全局变量来保存所有事件、用户等,当我从服务器获取信息时,请将其放在那里(并在从服务器获取某些内容之前检查那里),也许在某种本地存储中(以及我如何使用主干关系来做到这一点?
我的另一个想法是让每个事件都有自己独立的数据,问题是我每次点击事件时都可能会发送冗余数据。
你推荐什么方式?
谢谢!
就像@mu_is_too_short评论的那样,骨干关系可能是你有兴趣研究的东西。使用主干关系,将自动创建模型和子模型集合,并且可以跨父子关系管理事件。
我只给你一些示例代码,以便你尝一尝。示例代码的一部分可能如下所示。
用户有许多事件:
User = Backbone.RelationalModel.extend({
relations: [
type: Backbone.HasMany, // Type of relationship
key: 'events', // How we reference the sub-models in collection
relatedModel: 'Event', // The sub-model type
collectionType: 'EventCollection', // The sub-model collection
reverseRelation: {
key: 'belongsToUser' // Key we use to refer to the parent
}
],
// Other Backbone.Model properties and functions
});
当您创建主干关系模型时,它会自动为您创建一个子模型集合,以您指定的"键"命名。因此,您拥有的每个用户都将整理自己的相关事件集合。
基本上,当您创建或获取用户时,您会为其提供对所需相关模型的引用。例如,您的用户 id=1 可能需要事件 5、7 和 11。(我只是使用 ID)。只要这些引用是以数组形式定义的,那么你就可以使用 Relation 的 fetchRelated 方法延迟加载它们。
myUser = new User();
myUser.set({
name: 'RayMysterio',
age: '26',
events: [5, 7, 11] // Or this might just come with the User object from your server
});
myUser.fetchRelated('events');
// This will go fetch the related events for this user model from the URL you designate.
myUser.get('events');
// The collection of events are treated like an attribute of the User model.
myUser.get('events').find(function(eventModel){
return // some find condition - or whatever you want to do on that collection
});
您可能希望将某些侦听器绑定到子模型。
myUser.bind('add:events', function(model, collection) {
// Whatever code you want to happen when new models are added to the user events coll
});
等等等等。
这是产生一对一、一对多和反向关系的好方法。这是非常关键的。定义模型之间的关系并创建模型时。
例如,您创建用户模型的新实例。
主干关系会自动创建反向链接(事件模型具有由反向关系键"belongsToUser"(或任何您命名的名称)定义的属性)。这使得上下遍历模型/子模型层次结构非常方便。
根据您的关系需求,这似乎很合适。
如果你想要多对多,有一种迂回的方法(使用中间模型),但我发现这有点不稳定,我避免它。Paul-Uithol 更新 Backbone-Relational 已经有一段时间了,并且不断添加新功能。起初,学习曲线对我来说有点困难,但一旦你开始习惯它,它就非常方便。
注意:只是为了强调,莫塞尔曼推荐了Require.js我也非常同意这一点。它使我的代码更易于管理。您可以修改(包装)骨干关系代码,使其符合AMD标准,并且可以完美地与Require配合使用。
更新:骨干关系现在支持require.js自2014年4月1日0.8.8版本起 - 感谢Kenneth
理论上,您可以加载所有单独的集合,然后在进行渲染时对集合使用本地过滤来获取相关模型。
当然,您必须考虑安全问题。
至少对我来说,从你的问题中,我并不完全清楚你将如何处理你获取的信息,但我会尽力回答。
我的假设是,您有某种带有一些额外数据的事件,您需要显示与此相关的信息。然后,您还需要能够执行诸如添加注释等操作。
正如我所说,您可以考虑执行以下操作:
var Events = Backbone.Collection.extend({
url: '/events', // You might want to let the app return only an account's events or something, not just ALL events.
initialize: function(){
this.fetch();
}
});
var Comments = Backbone.Collection.extend({
url: '/comments',
initialize: function(){
_.bindAll(this, 'getEventComments');
this.fetch();
},
getEventComments: function(event_id){
return _.filter(this.models, function(model){ return model.get('event_id') == event_id; });
}
});
//etc
通过使用下划线的过滤功能,您可以在每次需要时(例如在渲染时)非常快速地获取相关模型。
在某种程度上,这与您在服务器端脚本中执行的操作相同。一些数据库保存所有带有记录的表,就像您的集合将在此处所做的那样,您的代码只是根据某些输入向数据库询问相关表。
最后,我将始终将Require.js与Backbone相结合地指向人们。无耻地参考我今天给出的一个答案,看看吧,无论如何都会让生活更轻松:骨干设计