我的Backbone应用程序正在与构建在MongoDB之上的REST API进行通信,因此我的对象的“自然”ID实际上是MongoIDs
。当序列化为JSON时,它们看起来像:
"_id":{"$id":"505099e998dee4db11000001"}
Backbone documentation提到您可以为您的Backbone模型的id属性指定另一个名称而不是id
(使用idAttribute
),但是,由于MongoIDs的字符串表示是嵌套的,只需使用{ {1}}无法直接使用JSON。
除了在服务器端重写属性之外,还有其他方法吗?
更新:
这就是我在服务器端做的事情:
idAttribute: '_id'
我知道我可以做$m = new Mongo();
$posts = $m->mydatabase->posts->find();
$out = array();
foreach ($posts as $post) {
$out[] = $post;
}
echo json_encode($out);
之类的事情,但这正是我想要避免的事情!
答案 0 :(得分:16)
这听起来像是parse()
的一个很好的例子。
由于您的Mongo JSON最终发送:
"_id":{"$id":"505099e998dee4db11000001"}
为什么不使用Backbone解析来正确命名传入数据呢?
parse: function(response) {
response.id = response._id['$id'];
delete response._id;
return response;
}
或类似的东西。同样,由于Backbone将使用'id'将ID作为JSON发送,您的服务器可能会采用该方式并以另一种方式“翻译”它。
如果您想使用其他id attribute,_id
,则只需使用以下代码替换上述解析:
idAttribute: '_id',
parse: function(response) {
response._id = response._id['$id'];
return response;
}
什么最适合你。 : - )
答案 1 :(得分:5)
最好在浏览器中进行转换,以便从服务器上移除计算。所以你想要创建一个基本MongoModel,然后你可以从MongoModel而不是Backbone.Model扩展。
MongoModel = Backbone.Model.extend({
// this handle conversion between the mongo's _id and backbone id
// this is best done on the client side to alleviate server load
//_id : { "$oid" : ... } <--> id
parse : function (response) {
response.id = response._id.$oid;
delete response._id;
return response;
},
toJSON : function () {
var
json = Backbone.Model.prototype.toJSON.apply(this);
json._id = {'$oid':json.id};
delete json.id;
return json;
}
});
答案 2 :(得分:3)
查看各种建议的选项,我发现最简单的方法是做你想要避免的事情。 (使用解析确实可以工作)
$m = new Mongo();
$posts = $m->mydatabase->posts->find();
$out = array();
foreach ($posts as $post) {
// populate an id field
$post['id']=$post['_id']->{'$id'},
$out[] = $post;
}
echo json_encode($out);
如果您希望模型在同步时将其发回,请保持$post['_id']
。
我更喜欢更正API,因为更多客户端可能想要连接到它。
答案 3 :(得分:0)
在Ruby中,我能够做到以下几点:
items.find.to_a.map do |item| frombsonid(item) end.to_json def frombsonid(obj) obj.merge({'_id' => obj['_id'].to_s}) end
当您获得数据时,您可以将字符串转换为BSON :: ObjectId
def tobsonid(id) BSON::ObjectId.fromstring(id) end
因此,我们的想法是用字符串版本BSON :: ObjectId
替换每个项目中的_id在骨干中你可以添加
idAttribute: "_id",
在PHP中,您将使用不同的语法和方法,但我相信很有可能复制它。
答案 4 :(得分:0)
您的PHP代码是Backbone将与之交互的REST API,因此 it 应该处理Mongo的复杂_id
属性到简单id
字符串的抽象寻找。这绝对是API的工作。
Backbone或您API的任何其他消费者,不应该对Mongo或_id
了解任何信息。
为什么呢?
因为如果你要从Mongo切换到没有_id
的其他Db,那么你的API仍然很好,因为所有暴露的都是id
,这是超级通用的。所以你最初的想法实际上是最好的想法(尽管你想要将这段代码抽象成可以重用于所有模型的东西,而不仅仅是帖子)。