【问题标题】:Overriding Backbone.sync覆盖 Backbone.sync
【发布时间】:2011-10-25 22:36:46
【问题描述】:

我正在尝试覆盖 Backbone.sync,以便在每次获取模型时设置“id”属性。这样,我确信下一个 model.save() 将触发 update 而不是 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())。知道我做错了什么吗?

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    听起来您可能想要覆盖 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-');
        }
    }
    

    【讨论】:

    • 同意。 Backbone.sync 更多关于您的传输/协议。您覆盖它以处理将“创建”、“更新”等动词映射到您的技术。默认情况下,Backbone.sync 是 HTTP/REST,但如果您需要其他内容(如 Socket.io 或本地存储),可以将其更改。如果你想对数据做一些事情(比如设置 ID),它应该像你建议的那样在模型中发生。
    • @BrianGenisio 你能告诉我如何同时使用 parse 和 fetch 的成功回调吗?我想使用解析来隔离元数据,然后我的渲染逻辑成功。但是如果我定义 model.parse 成功回调永远不会被调用。
    • @BlackDivine 你是否也覆盖了set 但没有返回任何东西?还是您在某个地方遇到异常?如果您查看fetch 的源代码,我看不到任何其他方式。 documentcloud.github.com/backbone/docs/backbone.html#section-40
    • 感谢@BrianGenisio,我发现了错误。我已经将视图绑定到 model.change 并且搞砸了:)
    【解决方案2】:

    @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);
                                 }
                   }
    
                }   
            );  
    

    【讨论】:

    • 我看不到你在这里做什么。实际上,我的问题更多是设计问题,因为我认为最好的方法是在服务器端生成一个 id 并返回它。然后 Backbone 自动将 id 设置为模型。为什么要将整个结果设置为 id?您使用的 model.new() 语法是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2011-06-11
    相关资源
    最近更新 更多