Backbone.js模型事件 #
一、事件概述 #
1.1 什么是事件 #
Backbone.js的事件系统是一个发布订阅模式的实现,允许对象之间进行松耦合的通信。
text
事件系统
├── 发布者:触发事件的对象
├── 订阅者:监听事件的对象
└── 事件:两者之间的通信桥梁
1.2 Model继承Events #
所有Backbone模型都继承了Events模块:
javascript
var user = new Backbone.Model();
user.on('change', function() {
console.log('模型已变化');
});
user.set('name', '张三');
二、事件绑定 #
2.1 on方法 #
javascript
var user = new Backbone.Model();
user.on('change', function(model) {
console.log('模型已变化');
});
user.set('name', '张三');
2.2 绑定多个事件 #
javascript
var user = new Backbone.Model();
user.on('change destroy sync', function(model) {
console.log('事件触发');
});
2.3 事件映射 #
javascript
var user = new Backbone.Model();
user.on({
'change': function() {
console.log('change事件');
},
'destroy': function() {
console.log('destroy事件');
},
'sync': function() {
console.log('sync事件');
}
});
2.4 绑定上下文 #
javascript
var UserView = Backbone.View.extend({
initialize: function() {
this.model.on('change', this.render, this);
},
render: function() {
console.log(this);
return this;
}
});
2.5 listenTo方法 #
javascript
var UserView = Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
return this;
}
});
2.6 on vs listenTo #
| 方法 | 说明 | 内存管理 |
|---|---|---|
| on | 直接绑定 | 需手动解绑 |
| listenTo | 监听其他对象 | 视图销毁时自动解绑 |
三、模型事件类型 #
3.1 change事件 #
javascript
var user = new Backbone.Model();
user.on('change', function(model, options) {
console.log('模型属性已变化');
console.log('变化的属性:', model.changedAttributes());
});
user.set('name', '张三');
3.2 change:attr事件 #
javascript
var user = new Backbone.Model();
user.on('change:name', function(model, value, options) {
console.log('name已变化为:', value);
});
user.on('change:age', function(model, value, options) {
console.log('age已变化为:', value);
});
user.set({ name: '张三', age: 25 });
3.3 destroy事件 #
javascript
var user = new Backbone.Model({ id: 1 });
user.on('destroy', function(model, collection, options) {
console.log('模型已销毁');
});
user.destroy();
3.4 sync事件 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users'
});
var user = new User({ id: 1 });
user.on('sync', function(model, response, options) {
console.log('同步成功');
console.log('服务器响应:', response);
});
user.fetch();
3.5 request事件 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users'
});
var user = new User({ id: 1 });
user.on('request', function(model, xhr, options) {
console.log('请求已发送');
});
user.fetch();
3.6 error事件 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users'
});
var user = new User({ id: 999 });
user.on('error', function(model, response, options) {
console.log('请求失败');
console.log('状态码:', response.status);
});
user.fetch();
3.7 invalid事件 #
javascript
var User = Backbone.Model.extend({
validate: function(attrs) {
if (!attrs.name) {
return '姓名不能为空';
}
}
});
var user = new User();
user.on('invalid', function(model, error, options) {
console.log('验证失败:', error);
});
user.set({ name: '' }, { validate: true });
四、事件触发 #
4.1 trigger方法 #
javascript
var user = new Backbone.Model();
user.on('custom:event', function(data) {
console.log('自定义事件触发:', data);
});
user.trigger('custom:event', { message: 'Hello' });
4.2 传递参数 #
javascript
var user = new Backbone.Model();
user.on('notify', function(message, type) {
console.log('[' + type + ']', message);
});
user.trigger('notify', '操作成功', 'success');
user.trigger('notify', '操作失败', 'error');
4.3 触发多个事件 #
javascript
var user = new Backbone.Model();
user.on('event1 event2 event3', function() {
console.log('事件触发');
});
user.trigger('event1 event2');
五、事件解绑 #
5.1 off方法 #
javascript
var user = new Backbone.Model();
var handler = function() {
console.log('事件触发');
};
user.on('change', handler);
user.off('change', handler);
5.2 解绑所有事件 #
javascript
var user = new Backbone.Model();
user.on('change', function() {});
user.on('destroy', function() {});
user.off();
5.3 解绑特定事件 #
javascript
var user = new Backbone.Model();
user.on('change', function() {});
user.on('destroy', function() {});
user.off('change');
5.4 解绑特定处理函数 #
javascript
var user = new Backbone.Model();
var handler1 = function() { console.log('handler1'); };
var handler2 = function() { console.log('handler2'); };
user.on('change', handler1);
user.on('change', handler2);
user.off('change', handler1);
5.5 stopListening方法 #
javascript
var view = new Backbone.View();
var model = new Backbone.Model();
view.listenTo(model, 'change', function() {
console.log('模型变化');
});
view.stopListening(model);
5.6 解绑所有监听 #
javascript
var view = new Backbone.View();
var model1 = new Backbone.Model();
var model2 = new Backbone.Model();
view.listenTo(model1, 'change', function() {});
view.listenTo(model2, 'change', function() {});
view.stopListening();
六、一次性事件 #
6.1 once方法 #
javascript
var user = new Backbone.Model();
user.once('change', function() {
console.log('只触发一次');
});
user.set('name', '张三');
user.set('name', '李四');
6.2 listenToOnce方法 #
javascript
var view = new Backbone.View();
var model = new Backbone.Model();
view.listenToOnce(model, 'change', function() {
console.log('只触发一次');
});
model.set('name', '张三');
model.set('name', '李四');
七、事件对象 #
7.1 事件回调参数 #
javascript
var user = new Backbone.Model();
user.on('change', function(model, options) {
console.log('模型:', model);
console.log('选项:', options);
});
user.set('name', '张三', { silent: false });
7.2 change事件参数 #
javascript
var user = new Backbone.Model();
user.on('change:name', function(model, value, options) {
console.log('模型:', model);
console.log('新值:', value);
console.log('选项:', options);
});
user.set('name', '张三');
7.3 sync事件参数 #
javascript
var User = Backbone.Model.extend({
urlRoot: '/api/users'
});
var user = new User({ id: 1 });
user.on('sync', function(model, response, options) {
console.log('模型:', model);
console.log('响应:', response);
console.log('选项:', options);
});
user.fetch();
八、事件高级用法 #
8.1 事件命名空间 #
javascript
var user = new Backbone.Model();
user.on('change:name', function() {
console.log('name变化');
});
user.on('change:age', function() {
console.log('age变化');
});
user.on('change', function() {
console.log('任意属性变化');
});
8.2 事件冒泡 #
Collection会代理Model的事件:
javascript
var User = Backbone.Model.extend({});
var Users = Backbone.Collection.extend({
model: User
});
var users = new Users();
users.on('change', function(model) {
console.log('集合中的模型变化:', model.get('name'));
});
var user = new User({ name: '张三' });
users.add(user);
user.set('name', '李四');
8.3 事件队列 #
javascript
var user = new Backbone.Model();
user.on('change', function() {
console.log('处理器1');
});
user.on('change', function() {
console.log('处理器2');
});
user.on('change', function() {
console.log('处理器3');
});
user.set('name', '张三');
8.4 条件事件 #
javascript
var User = Backbone.Model.extend({
initialize: function() {
this.on('change:status', function(model, status) {
if (status === 'active') {
this.trigger('activated');
} else if (status === 'inactive') {
this.trigger('deactivated');
}
});
}
});
var user = new User();
user.on('activated', function() {
console.log('用户已激活');
});
user.on('deactivated', function() {
console.log('用户已停用');
});
user.set('status', 'active');
九、实用示例 #
9.1 状态管理 #
javascript
var Task = Backbone.Model.extend({
defaults: {
status: 'pending'
},
initialize: function() {
this.on('change:status', this.onStatusChange);
},
onStatusChange: function(model, status) {
var events = {
'pending': 'pending',
'in_progress': 'started',
'completed': 'completed',
'cancelled': 'cancelled'
};
this.trigger(events[status] || 'statusChange', this);
},
start: function() {
this.set('status', 'in_progress');
},
complete: function() {
this.set('status', 'completed');
},
cancel: function() {
this.set('status', 'cancelled');
}
});
var task = new Task();
task.on('started', function() {
console.log('任务已开始');
});
task.on('completed', function() {
console.log('任务已完成');
});
task.start();
task.complete();
9.2 自动保存 #
javascript
var Document = Backbone.Model.extend({
urlRoot: '/api/documents',
initialize: function() {
this.on('change', this.autoSave, this);
},
autoSave: _.debounce(function() {
if (!this.isNew() || this.hasContent()) {
this.save();
}
}, 1000),
hasContent: function() {
return this.get('title') || this.get('content');
}
});
9.3 属性联动 #
javascript
var User = Backbone.Model.extend({
initialize: function() {
this.on('change:firstName change:lastName', this.updateFullName);
this.on('change:birthDate', this.updateAge);
},
updateFullName: function() {
var fullName = (this.get('firstName') || '') + ' ' + (this.get('lastName') || '');
this.set('fullName', fullName.trim(), { silent: true });
},
updateAge: function() {
var birthDate = new Date(this.get('birthDate'));
var now = new Date();
var age = now.getFullYear() - birthDate.getFullYear();
this.set('age', age, { silent: true });
}
});
9.4 事件日志 #
javascript
var BaseModel = Backbone.Model.extend({
initialize: function() {
this.on('all', function(eventName) {
console.log('[Event]', eventName, this.toJSON());
});
}
});
var User = BaseModel.extend({});
var user = new User();
user.set('name', '张三');
十、总结 #
10.1 事件方法 #
| 方法 | 说明 |
|---|---|
| on(event, callback, context) | 绑定事件 |
| off(event, callback) | 解绑事件 |
| trigger(event, *args) | 触发事件 |
| once(event, callback, context) | 绑定一次性事件 |
| listenTo(obj, event, callback) | 监听其他对象事件 |
| stopListening(obj, event, callback) | 停止监听 |
| listenToOnce(obj, event, callback) | 一次性监听 |
10.2 模型事件 #
| 事件 | 触发时机 |
|---|---|
| change | 属性变化时 |
| change:attr | 特定属性变化时 |
| destroy | 模型销毁时 |
| sync | 同步成功时 |
| request | 请求开始时 |
| error | 请求或验证失败时 |
| invalid | 验证失败时 |
10.3 最佳实践 #
- 使用
listenTo而非on,便于内存管理 - 及时解绑不再需要的事件
- 使用事件命名空间组织事件
- 避免在事件回调中直接修改模型
- 合理使用
once和listenToOnce
最后更新:2026-03-28