Backbone.js事件基础 #
一、事件系统概述 #
1.1 什么是Events #
Events是Backbone.js的核心模块,实现了发布订阅模式(Publish/Subscribe Pattern)。
text
Events模块
├── 发布订阅模式
├── 松耦合通信
├── 所有组件继承
└── 独立使用
1.2 Events的作用 #
javascript
var object = {};
_.extend(object, Backbone.Events);
object.on('alert', function(msg) {
console.log('收到消息:', msg);
});
object.trigger('alert', 'Hello World');
1.3 继承Events #
所有Backbone组件都继承了Events:
javascript
Backbone.Model.prototype.on === Backbone.Events.on
Backbone.Collection.prototype.on === Backbone.Events.on
Backbone.View.prototype.on === Backbone.Events.on
Backbone.Router.prototype.on === Backbone.Events.on
二、事件绑定 #
2.1 on方法 #
javascript
var obj = _.extend({}, Backbone.Events);
obj.on('alert', function(message) {
console.log('Alert:', message);
});
obj.trigger('alert', 'Hello');
2.2 绑定多个事件 #
javascript
obj.on('alert warning error', function(message) {
console.log('事件触发:', message);
});
obj.trigger('alert', 'Alert message');
obj.trigger('warning', 'Warning message');
2.3 事件映射 #
javascript
obj.on({
'alert': function(msg) {
console.log('Alert:', msg);
},
'warning': function(msg) {
console.log('Warning:', msg);
},
'error': function(msg) {
console.log('Error:', msg);
}
});
obj.trigger('alert', 'Alert!');
obj.trigger('warning', 'Warning!');
2.4 绑定上下文 #
javascript
var handler = function() {
console.log(this.name);
};
obj.on('alert', handler, { name: 'Context Object' });
obj.trigger('alert');
2.5 传递参数 #
javascript
obj.on('custom', function(a, b, c) {
console.log(a, b, c);
});
obj.trigger('custom', 1, 2, 3);
三、事件触发 #
3.1 trigger方法 #
javascript
obj.on('greet', function(name) {
console.log('Hello, ' + name + '!');
});
obj.trigger('greet', 'World');
3.2 触发多个事件 #
javascript
obj.on('event1 event2 event3', function() {
console.log('事件触发');
});
obj.trigger('event1 event2');
3.3 事件对象 #
javascript
obj.on('save', function(data, options) {
console.log('数据:', data);
console.log('选项:', options);
});
obj.trigger('save', { name: '张三' }, { silent: false });
四、事件解绑 #
4.1 off方法 #
javascript
var handler = function() {
console.log('事件触发');
};
obj.on('alert', handler);
obj.off('alert', handler);
4.2 解绑所有事件 #
javascript
obj.on('alert', function() {});
obj.on('warning', function() {});
obj.off();
4.3 解绑特定事件 #
javascript
obj.on('alert', function() {});
obj.on('warning', function() {});
obj.off('alert');
4.4 解绑特定处理函数 #
javascript
var handler1 = function() { console.log('Handler 1'); };
var handler2 = function() { console.log('Handler 2'); };
obj.on('alert', handler1);
obj.on('alert', handler2);
obj.off('alert', handler1);
4.5 解绑特定上下文 #
javascript
var context1 = { name: 'Context 1' };
var context2 = { name: 'Context 2' };
obj.on('alert', function() {}, context1);
obj.on('alert', function() {}, context2);
obj.off('alert', null, context1);
五、一次性事件 #
5.1 once方法 #
javascript
obj.once('alert', function(message) {
console.log('只触发一次:', message);
});
obj.trigger('alert', 'First');
obj.trigger('alert', 'Second');
5.2 once与上下文 #
javascript
obj.once('alert', function() {
console.log(this.name);
}, { name: 'Context' });
obj.trigger('alert');
5.3 once映射 #
javascript
obj.once({
'event1': function() { console.log('Event 1'); },
'event2': function() { console.log('Event 2'); }
});
obj.trigger('event1');
obj.trigger('event1');
六、监听其他对象 #
6.1 listenTo方法 #
javascript
var view = _.extend({}, Backbone.Events);
var model = _.extend({}, Backbone.Events);
view.listenTo(model, 'change', function() {
console.log('模型已变化');
});
model.trigger('change');
6.2 listenTo vs on #
| 方法 | 说明 | 内存管理 |
|---|---|---|
| on | 直接绑定 | 需手动解绑 |
| listenTo | 监听其他对象 | 自动解绑 |
6.3 stopListening方法 #
javascript
view.listenTo(model, 'change', handler);
view.stopListening(model);
view.stopListening();
view.stopListening(model, 'change');
6.4 listenToOnce方法 #
javascript
view.listenToOnce(model, 'change', function() {
console.log('只触发一次');
});
model.trigger('change');
model.trigger('change');
七、事件对象 #
7.1 _events属性 #
javascript
obj.on('alert', function() {});
obj.on('alert', function() {});
console.log(obj._events);
7.2 _listeners属性 #
javascript
view.listenTo(model, 'change', function() {});
console.log(view._listeners);
7.3 _listeningTo属性 #
javascript
view.listenTo(model, 'change', function() {});
console.log(view._listeningTo);
八、实用示例 #
8.1 事件总线 #
javascript
var EventBus = _.extend({}, Backbone.Events);
EventBus.on('user:login', function(user) {
console.log('用户登录:', user.name);
});
EventBus.on('user:logout', function() {
console.log('用户登出');
});
EventBus.trigger('user:login', { name: '张三' });
EventBus.trigger('user:logout');
8.2 模块通信 #
javascript
var UserModule = {
init: function() {
EventBus.on('user:fetch', this.fetchUser, this);
},
fetchUser: function(id) {
console.log('获取用户:', id);
EventBus.trigger('user:fetched', { id: id, name: '张三' });
}
};
var UIModule = {
init: function() {
EventBus.on('user:fetched', this.renderUser, this);
},
renderUser: function(user) {
console.log('渲染用户:', user.name);
}
};
UserModule.init();
UIModule.init();
EventBus.trigger('user:fetch', 1);
8.3 状态通知 #
javascript
var StateManager = _.extend({
state: {},
set: function(key, value) {
var oldValue = this.state[key];
this.state[key] = value;
this.trigger('change:' + key, value, oldValue);
this.trigger('change', key, value, oldValue);
},
get: function(key) {
return this.state[key];
}
}, Backbone.Events);
StateManager.on('change:theme', function(newValue, oldValue) {
console.log('主题从', oldValue, '变为', newValue);
});
StateManager.set('theme', 'dark');
8.4 异步事件 #
javascript
var AsyncEvents = _.extend({
emitAsync: function(event) {
var args = arguments;
var self = this;
setTimeout(function() {
self.trigger.apply(self, args);
}, 0);
}
}, Backbone.Events);
AsyncEvents.on('async', function() {
console.log('异步事件触发');
});
console.log('Before');
AsyncEvents.emitAsync('async');
console.log('After');
九、总结 #
9.1 Events方法 #
| 方法 | 说明 |
|---|---|
| on(event, callback, context) | 绑定事件 |
| off(event, callback, context) | 解绑事件 |
| trigger(event, *args) | 触发事件 |
| once(event, callback, context) | 绑定一次性事件 |
| listenTo(obj, event, callback) | 监听其他对象事件 |
| stopListening(obj, event, callback) | 停止监听 |
| listenToOnce(obj, event, callback) | 一次性监听 |
9.2 最佳实践 #
- 使用
listenTo替代on,便于内存管理 - 使用事件总线实现模块通信
- 及时解绑不再需要的事件
- 使用命名空间组织事件
- 避免过度使用事件导致代码难以追踪
最后更新:2026-03-28