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 最佳实践 #

  1. 使用 listenTo 替代 on,便于内存管理
  2. 使用事件总线实现模块通信
  3. 及时解绑不再需要的事件
  4. 使用命名空间组织事件
  5. 避免过度使用事件导致代码难以追踪
最后更新:2026-03-28