骨干事件总线&同一页面上的多个视图

时间:2014-02-24 02:36:55

标签: javascript jquery events backbone.js backbone-events

我遇到了问题,我尝试使用简单的骨干事件总线

var eventBus = _.extend({}, Backbone.Events);

我在DOM中的多个视图下面有一个按钮,按钮是另一个视图,如下所示:

===================
===== CONTENT =====  <- VIEW 1 (content)
===================
BTN1 | BTN2 | BTN3   <- VIEW 2 (controls)

这在页面上重复多次。

问题是,当我触发一个事件时,它会触发页面上的所有视图。

在“控件”中我得到了:

events: {
    'click .check': 'checkMe',
}

checkMe: function(e) {
    e.preventDefault();
    eventBus.trigger('checkMe');
}

并在所有观点中:

initialize: function(options) {
    …
    eventBus.on('checkMe', this.checkMe, this);
},

checkMe: function() {
    alert("!");
}

正如我之前所说,当我点击一组按钮时,它会触发我在页面上的每个视图(内容)的事件,是否有任何方法可以使其正常工作?

谢谢你们!

1 个答案:

答案 0 :(得分:4)

我有一些选择。


你可以namespace your events。如果每个视图都有唯一的ID,您可以将这些事件连接起来:

eventBus.trigger('checkMe:' + uniqueId);

稍后在视图中像这样捕捉它

eventBus.on('checkMe:' + this.id, this.checkMe, this);

或者您可以使用uniqueId作为参数触发事件

eventBus.trigger('checkMe', {id: uniqueId});

像这样处理事件:

checkMe: function(params) {
    if(params.id === this.id) {
        alert("!");
    }
}

第三个选项可能是创建一个控制器对象,以在每组内容和控件之间进行调解。控制器将作为事件总线,每个事件总线分别处理控制器事件,防止全局事件问题。

---------------------------------------------
| ===================                       |
| ===== CONTENT =====  <- VIEW 1 (content)  | <- Controller Instance
| ===================                       |
| BTN1 | BTN2 | BTN3   <- VIEW 2 (controls) |
---------------------------------------------

假设您有一个集合,您可以迭代创建内容/控件集。 它看起来像这样(非常粗略。)这里的控制器只是一个事件总线,但可以根据需要保存更多逻辑。

collection.each(function(item) {
    var controller = _.extend({}, Backbone.Events);
    controller.onCheckMe = function () {
      contentView.performWork();
    };

    var contentView = new ContentView({
        performWork: function () {
            // TODO: do work here
        }
    });

    var controlsView = new ControlsView({
        events: {
            'click .check': 'checkMe',
        },
        checkMe: function(e) {
            e.preventDefault();
            this.trigger('checkMe');
        }
    );

    controller.listenTo(controlsView, 'checkme', controller.onCheckMe.bind(controller));

    // TODO: render the views here
});