我有一个包含许多网址的API,如:
/users/profile -> GET the currently connected user /users/bestfriend -> GET the currently connected users' best friend (most bestfriend of bestfriends) /users/wife -> GET the currently connected users' wife /users/friends -> GET the currently connected users' friends /users/bestfriends -> GET the currently connected users' best friends /users/childrens -> GET the currently connected users' childrens /users/neighbours -> GET the currently connected users' neighbours
我是Backbone的新手,我真的不知道当前连接的用户是应该作为集合提取还是作为示例的简单模型。
我知道当前的用户可能会像Backbone doc提到的那样被提升,但这不是重点,只是假设我无法提升当前的用户模型。
那么如何将我的提取重定向到API URL?
我应该每次都提供{"operation":"profile"}
或{"operation":"friends"}
这样的选项,还是在进行提取之前修改收集网址?
由于
答案 0 :(得分:1)
如果您希望使用集合的“外部”模型,请使用model.urlRoot
属性指定模型的URL。如果它是新模型(即id==null
),它会自动将ID附加到URL的末尾,并在创建时发送POST。否则它将在指定的URL上获取(GET)。
如果您不想在最后添加ID:只需覆盖model.url
即可生成您要获取/放置/发布到的实际端点URL。
集合还有一个名为url
的属性 - 如果未指定模型的url或urlRoot,则会将集合的url选为根(如果该模型是该集合的一部分)。
所以你可以做其中任何一个:
model.urlRoot = '/users/profile'; //appends id on put/delete requests
model.url = '/users/profile'; //direct endpoint. Can also be a function
collection.url = '/users/friends'; //fetch endpoint for collection. Could also be used by models to put to with appended id.
Backbone的文档非常全面且不言自明。我建议您阅读这些部分,例如Model.urlRoot
更新:根据您的新网址
我认为混淆是因为URL的设计方式。将端点视为复数/单数是不好的做法:
例:
/user/friends
- 很好地获取用户的所有朋友。但哪个用户?
更好的是:/users/{id}/friends
- 获取特定用户的朋友。
获取用户的特定朋友:/users/{id}/friends/{id}
我建议在您的网址中添加ID,以充分利用主干内置的REST功能。另外,只需定义自己的属性和逻辑,并使用单独的函数(如“save”)自行激活$.ajax
调用,并对成功/错误回调执行某些操作。
无论是模特还是收藏都将完全取决于您。幸运的是/不幸的是,在Backbone中有不止一种方法可以做到这一点。如果你遵循BB的方式,它将提供一种更简洁的方式,因为框架期望并遵循某些约定。如果没有,您可以随时自定义创建。我做过两种方式。自定义创建看起来更容易,遵循约定需要一些计划,但保持它更清洁,尽管隐藏/抽象程序员'引擎盖'的东西,而显式的ajax调用使它明确。
这是一个权衡。我建议重新构建您的端点并相应地使用url属性。其他只是对你和你的团队做有意义的事情并坚持下去。
答案 1 :(得分:1)
您必须创建与您的某个网址相关的多个模型和集合。
var Profile = Backbone.Model.extend({
url: "/users/profile"
});
var BestFriend = Backbone.Model.extend({
url: "/users/bestfriend"
});
// ...
var Friend = Backbone.Model.extend({});
var Friends = Backbone.Collection.extend({
model: Friend,
url: "/users/friends"
});
您还可以使用Friend
作为BestFriend
的父类:
var BestFriend = Friend.extend({
url: "/users/bestfriend"
});
甚至可以为每个人创建一个Person
类作为父级:
var Person = Backbone.Model.extend({});
var Friends = Backbone.Collection.extend({
model: Person,
url: "/users/friends"
});
var Profile = Person.extend({
url: "/users/profile"
});
var BestFriend = Person.extend({
url: "/users/bestfriend"
});
由于您有单独的URL来检索每个元素的数据,您应该进行多次提取:
var profile = new Profile();
var bestFriend = new BestFriend();
var friends = new Friends();
profile.fetch();
bestfriend.fetch();
friends.fetch();
您可以使用以下内容将所有元素引用到Profile
实例中:
var Profile = Person.extend({
url: "/users/profile",
initialize: function( opts ){
this.bestFriend = opt.bestfriend;
// ...
}
});
var bestFriend = new BestFriend();
var friends = new Friends();
var profile = new Profile({
bestfriend: bestfriend
});
有几种方法可以组织元素,也可以在它们上面听事件,但这只是一个品味问题,以及您更满意的架构。
答案 2 :(得分:1)
基本上我同意第一个答案,但为了简单起见,您可以开始为用户使用ID并单独获取它们。这可能会产生一些额外的负载,但它应该保持代码更清晰,直到您需要优化。
您可能会遇到当前API设计的问题。如果将来你想要妻子最好的朋友怎么办?您将拥有一个具有URL“/ user / wife”的对象,然后您会说“/ user / wife / bestfriend”。接下来有人想扩展它并拥有“/ user / wife / bestfriend / children /”。在后端解析会相当复杂。
基本上,不要为妻子和孩子单独调用,而是让配置文件调用返回相关用户的ID:
/profile
{
id: 165735,
name: "Peter",
age: 45,
wifeId: 246247,
childrenIds: [352356, 134098]
}
然后取妻子就是:
/users/246247
这会让妻子成为真正的用户而不仅仅是某人的妻子。您可以在检索用户时检查此处的安全性,因为您无论如何都要将关系存储在数据库中。