Backbone.js同步机制 #

一、同步概述 #

1.1 什么是Sync #

Backbone.sync 是Backbone.js中负责与服务器进行数据同步的核心方法。

text
Sync职责
├── 模型CRUD操作
├── 集合批量操作
├── RESTful API交互
└── 数据持久化

1.2 默认行为 #

javascript
var User = Backbone.Model.extend({
    urlRoot: '/api/users'
});

var user = new User({ id: 1 });
user.fetch();

1.3 同步方法映射 #

CRUD操作 HTTP方法 URL
create POST /api/users
read (model) GET /api/users/:id
read (collection) GET /api/users
update PUT /api/users/:id
patch PATCH /api/users/:id
delete DELETE /api/users/:id

二、fetch方法 #

2.1 模型fetch #

javascript
var User = Backbone.Model.extend({
    urlRoot: '/api/users'
});

var user = new User({ id: 1 });

user.fetch({
    success: function(model, response) {
        console.log('获取成功:', model.toJSON());
    },
    error: function(model, response) {
        console.log('获取失败:', response.status);
    }
});

2.2 集合fetch #

javascript
var Users = Backbone.Collection.extend({
    url: '/api/users'
});

var users = new Users();

users.fetch({
    success: function(collection, response) {
        console.log('获取成功:', collection.length);
    }
});

2.3 fetch选项 #

javascript
user.fetch({
    data: { fields: 'name,email' },
    reset: true,
    parse: true,
    success: function() {},
    error: function() {}
});
选项 说明
data 请求参数
reset 是否重置集合
parse 是否解析响应
success 成功回调
error 失败回调

2.4 返回Promise #

javascript
user.fetch().then(function() {
    console.log('获取成功');
}).fail(function() {
    console.log('获取失败');
});

三、save方法 #

3.1 创建模型 #

javascript
var user = new User();

user.save({ name: '张三', email: 'zhangsan@example.com' }, {
    success: function(model) {
        console.log('创建成功, ID:', model.id);
    }
});

3.2 更新模型 #

javascript
var user = new User({ id: 1 });

user.fetch().then(function() {
    user.save({ name: '李四' });
});

3.3 save选项 #

javascript
user.save(attrs, {
    wait: true,
    validate: true,
    patch: false,
    success: function() {},
    error: function() {}
});
选项 说明
wait 是否等待服务器响应才更新
validate 是否验证
patch 是否使用PATCH方法
success 成功回调
error 失败回调

3.4 patch更新 #

javascript
user.save({ name: '新名字' }, { patch: true });

3.5 wait选项 #

javascript
user.save({ name: '张三' }, {
    wait: true,
    success: function() {
        console.log('保存成功');
    }
});

四、destroy方法 #

4.1 删除模型 #

javascript
var user = new User({ id: 1 });

user.destroy({
    success: function() {
        console.log('删除成功');
    }
});

4.2 destroy选项 #

javascript
user.destroy({
    wait: true,
    success: function() {},
    error: function() {}
});

4.3 wait选项 #

javascript
user.destroy({
    wait: true,
    success: function() {
        console.log('服务器确认删除');
    }
});

4.4 新模型删除 #

javascript
var user = new User();

user.destroy();

五、同步事件 #

5.1 request事件 #

javascript
user.on('request', function(model, xhr, options) {
    console.log('请求已发送');
});

user.fetch();

5.2 sync事件 #

javascript
user.on('sync', function(model, response, options) {
    console.log('同步成功');
});

user.fetch();

5.3 error事件 #

javascript
user.on('error', function(model, response, options) {
    console.log('同步失败:', response.status);
});

user.fetch();

5.4 destroy事件 #

javascript
user.on('destroy', function(model, collection, options) {
    console.log('模型已销毁');
});

user.destroy();

六、自定义sync #

6.1 覆盖全局sync #

javascript
Backbone.sync = function(method, model, options) {
    console.log('方法:', method);
    console.log('模型:', model);
    console.log('选项:', options);
    
    return Backbone.ajaxSync(method, model, options);
};

6.2 模型级别sync #

javascript
var User = Backbone.Model.extend({
    urlRoot: '/api/users',
    
    sync: function(method, model, options) {
        options = options || {};
        options.headers = {
            'X-Custom-Header': 'value'
        };
        
        return Backbone.sync(method, model, options);
    }
});

6.3 添加认证Token #

javascript
var AuthModel = Backbone.Model.extend({
    sync: function(method, model, options) {
        options = options || {};
        options.headers = _.extend({
            'Authorization': 'Bearer ' + localStorage.getItem('token')
        }, options.headers);
        
        return Backbone.sync(method, model, options);
    }
});

七、实用示例 #

7.1 带加载状态的模型 #

javascript
var LoadingModel = Backbone.Model.extend({
    fetch: function(options) {
        var self = this;
        
        this.trigger('loading:start');
        
        options = options || {};
        var success = options.success;
        var error = options.error;
        
        options.success = function() {
            self.trigger('loading:end');
            if (success) success.apply(this, arguments);
        };
        
        options.error = function() {
            self.trigger('loading:end');
            if (error) error.apply(this, arguments);
        };
        
        return Backbone.Model.prototype.fetch.call(this, options);
    }
});

7.2 重试机制 #

javascript
var RetryModel = Backbone.Model.extend({
    maxRetries: 3,
    
    sync: function(method, model, options) {
        var retries = 0;
        var self = this;
        
        function attempt() {
            return Backbone.sync(method, model, options)
                .fail(function(xhr) {
                    if (xhr.status >= 500 && retries < self.maxRetries) {
                        retries++;
                        console.log('重试第', retries, '次');
                        return attempt();
                    }
                });
        }
        
        return attempt();
    }
});

7.3 缓存模型 #

javascript
var CachedModel = Backbone.Model.extend({
    cache: {},
    cacheTTL: 5 * 60 * 1000,
    
    fetch: function(options) {
        options = options || {};
        
        if (options.cache !== false) {
            var cached = this.getCache();
            if (cached) {
                this.set(cached.data);
                return $.Deferred().resolve().promise();
            }
        }
        
        var self = this;
        return Backbone.Model.prototype.fetch.call(this, options)
            .done(function() {
                self.setCache();
            });
    },
    
    getCache: function() {
        var key = this.url();
        var cached = this.cache[key];
        
        if (cached && Date.now() - cached.timestamp < this.cacheTTL) {
            return cached;
        }
        
        return null;
    },
    
    setCache: function() {
        var key = this.url();
        this.cache[key] = {
            data: this.toJSON(),
            timestamp: Date.now()
        };
    }
});

八、总结 #

8.1 同步方法 #

方法 说明
fetch(options) 获取数据
save(attrs, options) 保存数据
destroy(options) 删除数据

8.2 同步事件 #

事件 触发时机
request 请求开始时
sync 同步成功时
error 同步失败时
destroy 模型销毁时

8.3 最佳实践 #

  1. 合理使用wait选项
  2. 处理同步错误
  3. 添加认证Token
  4. 实现加载状态
  5. 考虑缓存策略
最后更新:2026-03-28