覆盖Backbone.sync

Clé*_*ent 2 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);
}
Run Code Online (Sandbox Code Playgroud)

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

nra*_*itz 7

听起来你可能想要覆盖Model.fetchModel.parse代替Backbone.sync.Backbone.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);
};
Run Code Online (Sandbox Code Playgroud)

这里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-');
    }
}
Run Code Online (Sandbox Code Playgroud)