12

我的 Backbone 应用程序正在与构建在 MongoDB 之上的 REST API 进行通信,因此我的对象的“自然”ID 确实是MongoIDs. 当序列化为 JSON 时,它们看起来像:

"_id":{"$id":"505099e998dee4db11000001"}

Backbone 文档提到,您可以为 Backbone 模型的 id 属性指定其他名称(id使用idAttribute),但是,由于 MongoID 的字符串表示是嵌套的,因此仅使用idAttribute: '_id'无助于直接使用 JSON。

除了在服务器端重写属性之外,有没有办法解决这个问题?

更新:

这是我在服务器端做的事情:

$m = new Mongo();
$posts = $m->mydatabase->posts->find();

$out = array();

foreach ($posts as $post) {
    $out[] = $post;
}

echo json_encode($out);

我知道我可以做类似的事情,$post['id'] = (string) $post['_id']; unset($post['_id']);但这正是我想要避免的!

4

5 回答 5

15

这听起来像是一个很好的例子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 属性_id您只需将上面的解析替换为以下代码:

idAttribute: '_id',

parse: function(response) {
    response._id = response._id['$id'];

    return response;
}

什么最适合你。:-)

于 2012-09-12T15:02:31.380 回答
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;
    }
});
于 2013-10-02T22:34:32.910 回答
3

Looking at various suggested options I found the easiest would be to do what you want to avoid. (Using parse does work though)

$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);

Keeping $post['_id'] if you want your model to send it back when syncing. I prefer correcting the API as more clients might want to connect to it.

于 2013-02-01T12:56:51.063 回答
0

您的 PHP 代码是 Backbone 将与之交互的 REST API,因此应该将 Mongo 的复杂_id属性抽象为id您正在寻找的简单字符串。这绝对是 API 的工作。

Backbone 或您的 API 的任何其他使用者不应该对 Mongo 或_id.

为什么?因为如果您要从 Mongo 切换到其他没有 的 Db _id,那么您的 API 仍然很好,因为曾经暴露的只是id,这是超级通用的。因此,您最初的想法实际上是最好的想法(尽管您希望将那段代码抽象为可用于所有模型的东西,而不仅仅是帖子)。

于 2015-01-14T07:45:21.187 回答
0

在 Ruby 中,我可以执行以下操作:

items.find.to_a.map 做 |item|
  来自bsonid(项目)
end.to_json

def frombsonid(obj) obj.merge({'_id' => obj['_id'].to_s}) 结束

当您取回数据时,您可以将字符串转换为 BSON::ObjectId

def tobsonid(id) BSON::ObjectId.fromstring(id) end

所以想法是用 BSON::ObjectId 的字符串版本替换每个项目中的 _id

在主干中,您可以添加

idAttribute: "_id", 

在 PHP 中,您将使用不同的语法和方法,但我相信完全可以复制这一点。

于 2013-01-08T16:16:23.180 回答