覆盖Backbone.sync

时间:2011-10-25 22:36:46

标签: javascript backbone.js

我正在尝试覆盖Backbone.sync,以便在每次获取模型时设置“id”属性。这样,我确信下一个model.save()将触发更新而不是 create ,即使fetch()没有响应id。

Backbone._sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
    var params = _.clone(options);
    params.success = function(model) {
        if(method == 'read' && model.isNew()) {
            var id = Math.floor(Math.random()*1000);
            model.set({ "id": id });
        }
        if(options.success) options.success(model);
    };
    Backbone._sync(method, model, params);
}

但传递给成功函数的模型似乎不是Backbone模型,而是一个对象。所以我不能使用任何方法(如model.isNew())。我知道我做错了什么?

2 个答案:

答案 0 :(得分:7)

听起来您可能想要覆盖Model.fetchModel.parse而不是Backbone.syncBackbone.sync只需要$.ajax()个选项,因此success回调只是从服务器接收JSON响应,而不是实例化模型。

默认Model.fetch()回调如下所示:

options.success = function(resp, status, xhr) {
    if (!model.set(model.parse(resp, xhr), options)) return false;
    if (success) success(model, resp);
};

此处model指的是当前实例,如您所愿。所以你可以考虑覆盖Model.fetch来添加一个id,如果它不在那里,或者,可能更好,覆盖model.parse(),这是默认的直通,并且用作你的服务器数据的钩子。我对你的随机数id实现并不感到兴奋,因为仍然有可能发生冲突,特别是如果你制作了很多模型 - 你可能会尝试使用model.cid(保证在客户端是唯一的,尽管它可能与服务器提供的ID冲突)或Underscore的_.uniqueId()

parse: function(resp, xhr) {
    if (this.isNew() && !resp.id) {
        resp.id = _.uniqueId('model-');
    }
}

答案 1 :(得分:1)

@nrabinowitz

只是为此添加更多的清晰度。我正在使用具有内置JSON支持的RedbeanPHP。一个问题是,当你创建一个对象时,它会在结果标记中返回该对象的新id,如果你想编辑它,你需要这个对象。

   // My model object is a User. (we are all Users in some way).
   var User = Backbone.Model.extend(
            {   
                url : "/user/rpc",
                defaults: {
                    email: "email",
                    password: "",
                    admin: 0
                },parse: function(resp, xhr) {
                               // check if the model is new, if so, set the id of this model for future requests so RedBean knows the id of this object.
                   if(this.new()){
                    this.set({"id":resp.result});
                    console.log(this);
                             }
               }

            }   
        );