Javascript 基于键的主干关系定义的正确方法
我已经看过很多次文档了,但是这方面我还是不清楚。我完全有可能认为主干关系做了它不做的事情 我正在寻找一种基于键定义关系的方法,以避免所有样板文件获取的废话 以经典艺术家和专辑为例: 艺术家有许多由album.artist\u id定义的相册 /api/artist/62351可能会返回Javascript 基于键的主干关系定义的正确方法,javascript,backbone.js,backbone-relational,Javascript,Backbone.js,Backbone Relational,我已经看过很多次文档了,但是这方面我还是不清楚。我完全有可能认为主干关系做了它不做的事情 我正在寻找一种基于键定义关系的方法,以避免所有样板文件获取的废话 以经典艺术家和专辑为例: 艺术家有许多由album.artist\u id定义的相册 /api/artist/62351可能会返回 { 身份证号码:62351, 姓名:“吉米·亨德里克斯” } 类似地/api/album?Artister_id=62351可能会返回 [ { 身份证号码:5678, 姓名:“你有经验吗?” 艺术家编号:623
{
身份证号码:62351,
姓名:“吉米·亨德里克斯”
}
类似地/api/album?Artister_id=62351可能会返回
[
{
身份证号码:5678,
姓名:“你有经验吗?”
艺术家编号:62351
},
{
id:4321,
名称:“轴心国:大胆如爱”,
艺术家编号:62351
}
]
我如何定义艺术家和专辑之间的关系
var hendrixInstance=新艺术家({id:62351});
获取('albums');
是否会根据专辑外键艺术家id获取并返回专辑集?这一定是我还没有尝试过的key/keySource/keyDestination的一些排列,或者是主干关系网没有试图解决的一个问题,但我的doc groking失败了,我认为一个简洁的答案可能会对未来的谷歌用户有所帮助
var-Artist=Backbone.RelationalModel.extend({
urlRoot:“/api/artist”,
关系:[{
key:'albums',//文档说这是外键名,但实际上不是这样显示的。需要keySource/Destination吗?
类型:Backbone.HasMany,
反向关联:{
关键词:“艺术家”,
类型:主干网
}
}]
});
var Album=Backbone.RelationalModel.extend({
urlRoot:“/api/album”
});
有一个示例模型引用了它的自邻接列表样式和parent_id我正面临着这个问题(),经过两天的研究和源代码研究,我认为key/keySource/keysidential无法完成这项工作(如果我错了,请纠正我) 因此,我最终创建了自己的关系类型,到目前为止效果良好。这可能不是一个好的解决方案,但希望能帮助你
var LazyMany = Backbone.HasMany.extend({
setRelated: function (related) {
var relation = this.options
, instance = this.instance
;
if (related && !_.result(related, 'url')) {
related.url = relation.relatedModel.prototype.urlRoot +
'?' + relation.reverseRelation.key + '=' + instance.id;
}
return LazyMany.__super__.setRelated.apply(this, arguments);
}
});
然后在您的模型中:
var Album = Backbone.RelationalModel.extend({
urlRoot: '/api/album/'
});
var Artist = Backbone.RelationalModel.extend({
urlRoot: '/api/artist/',
relations:[{
key: 'albums',
type: LazyMany,
includeInJSON: false,
relatedModel: Album,
reverseRelation: {
key: 'artist',
// I didn't test this, I don't have artist_id, artist is "id" in my app
keySource: 'artist_id',
keyDestination: 'artist_id',
includeInJSON: 'id'
}
}]
});
因此,如果您没有定义collectionType或您的收藏没有url字段,LazyMany将使用url创建一个收藏:/api/album/?artist=62351
。
然后您只需要获取集合:artist.get('albums').fetch()
希望这能有所帮助,我仍在寻找更好的解决方案。因此,@xzhang的上述方法让我不断重复这个问题。首先,我希望在这一点上被证明是错误的,但我还没有找到一种方法,可以在没有额外定制代码的情况下处理这个问题。因为在我看来,这是一段一夫一妻制关系的一个难以置信的基本例子,我仍然抱着希望,我只是没有得到一些明显的东西 以下是我为处理这种情况所做的事情。不幸的是,当调用someobject.fetch('somerelationship')时,它仍然不能自动从服务器获取数据,这正是我真正想要的。解析函数对于大多数人来说不是必需的,但是对于我正在调用的api来说却是必需的 首先,我设置了一个要从中扩展的基本集合:
var BaseCollection = Backbone.Collection.extend({
initialize: function(models, options) {
if (_.isObject(options.relation)) {
this.url = '/api/'
+ options.relation.keySource
+ '?search.'+options.relation.reverseRelation.keySource
+ '=' + options.foreignId;
}
},
parse: function(res) { return res.success ? res.list : res },
});
然后是一个可重用的助手函数(可能会被滚动到BaseCollection中)来帮助创建关系
function collectionOptions(instance) {
return {"relation":this, "foreignId":instance.get('id') };
};
最后,这些关系被告知使用BaseCollection作为它们的CollectionType,并且collectionOptions()助手被分配给set collectionOptions
var Form = BaseModel.extend({
urlRoot: '/api/form',
relations:[
{
key: 'fills',
keySource: 'fill',
relatedModel: Fill,
type: Backbone.HasMany,
collectionOptions: collectionOptions,
collectionType: BaseCollection,
reverseRelation: {
key: 'form',
keySource: 'form_id',
type: Backbone.HasOne
}
},{
key: 'children',
keySource: 'form',
relatedModel: 'Form',
type: Backbone.HasMany,
collectionOptions: collectionOptions,
collectionType: BaseCollection,
reverseRelation: {
key: 'parent',
keySource: 'parent_id',
type: Backbone.HasOne
}
}
]
});
这允许我避免更改服务器端API以返回ID列表,然后单独获取这些ID。相反,我可以:
var form = new Form({id:1});
form.get('children').fetch();
form.toJSON(); //now has {id:1, ..., ..., children:[child,child,child,...]}
在第一次调用.get('children')时自动获取子对象的扩展只是一张罚单,但我还没有发现如何在不修改主干关系本身的情况下实现这一点。谢谢@xzhang,我很高兴看到我不是唯一一个期望主干关系有不同的人。我尝试了你的方法,它确实有效,但经过几次额外的迭代后,我最终使用了一种变体。