backbone.js - 我应该在backbone.js 中使用中央事件总线吗?

标签 backbone.js event-handling

我目前正在开发我的第一个backbone.js 应用程序。事件的概念对我来说非常熟悉,但是我是否应该使用中央事件调度程序存在疑问。通常我看到这两种方法:

  • 直接将事件发布者和事件接收者连接在一起。 (我从这种方法开始。)
  • 使用事件总线并将发布者和接收者连接到该总线。

  • 就 e 而言,使用事件总线是否有利? G。应用程序的长期可维护性和事件的可追溯性?

    最佳答案

    是使用中央事件总线还是直接将事件连接在一起,应根据具体情况进行评估。根据情况,有时您会偏爱其中一个。

    由于发布者和接收者不是紧密耦合的,我将尽可能使用中央事件总线。在我看来,这使您的代码更易于维护和灵活。

    当您有以下情况时,我发现中央事件总线非常有用:

  • 单个事件发布实例和多个事件接收器。
  • 许多事件发布实例和单个事件接收器

  • 当事件接收器实例或发布器实例是动态的并因此在应用程序的生命周期内被创建和销毁时,中央事件总线在上述情况下的好处变得更加明显。例如,考虑以下单页应用程序:
  • 单页应用程序必须拉伸(stretch)以适应浏览器窗口的宽度。
  • 单页应用程序主要是一组选项卡式 View ,但是选项卡的数量是动态的,因为它们是由用户创建和销毁的
  • 选项卡的内容都是不同的,除了它们有一个主要的内容区域,在考虑其他同级元素的宽度后,必须拉伸(stretch)以适应可用的宽度
  • 由于选项卡的内容不断变化,需要在许多不同的点调整大小。

  • 在上述情况下,无论具体场景如何,中央总线模型都非常有效。一个代码示例是:

    应用层
    var App = {
    
        init: function () {
            // Event to resize width of element to remaining width
            App.Events.on("fitRemainingWidth:app", this.fitRemainingWidth);
         },
    
        // event pub sub for the app.
        Events: _.extend({}, Backbone.Events),
    
        // function that expands an element, or elements to the remaining width in the window. 
        fitRemainingWidth: function(targetEls) {
            var els = $(targetEls);
            _.each(els, function (e) {
                var el = $(e);
                var cont = el.parent();
                newWidth = cont.innerWidth();
                otherElements = cont.children().not(el);
                otherElementsWidth = 0;
    
                otherElements.each(function () {
                    otherElementsWidth += $(this).outerWidth();
                });
    
                el.width(newWidth - otherElementsWidth);
            });
        }
    }
    

    在您看来

    每当需要调整某个东西的大小时,您就会触发该事件,例如:
    App.Events.trigger("fitRemainingWidth:app", this.$(".main-content"), this);
    

    正如您所看到的,这非常有用,因为 fitRemainingWidth 函数可以应用于任何事物,而且您永远不知道将来哪些 View 可能想要使用它,或者何时需要调用它。

    所以我想当我发现不使用中央事件总线更可取时,我应该继续。我确信还有其他情况,但是对我来说主要的情况是接收器需要连接到发布者的特定实例。例如,如果我们继续使用选项卡式应用程序示例,假设每个选项卡的内容是特定人员邮箱的拆分 View 。在每个拆分 View 中,有一个列表 Pane 显示电子邮件集合和一个阅读 Pane ,显示列表中当前所选邮件的内容。

    在这种情况下,我们希望在单击电子邮件时触发“selected:email”事件,并将适当的阅读 Pane 绑定(bind)到它,以便它可以显示电子邮件的内容。

    假设我们打开了十个邮箱选项卡,每个选项卡都有自己的电子邮件列表 Pane 和阅读 Pane 。这就形成了十个电子邮件列表和十个阅读 Pane 。如果我在从其中一个列表中触发“selected:email”时为此场景使用中央事件总线,那么从事件总线接收这些事件的阅读 Pane 将需要有自己的智能来尝试和工作确定所选电子邮件是否是他们需要显示的内容。每个阅读 Pane 都尝试解决这个问题并不是真正可取的,并且涉及到不必要的逻辑。对于阅读 Pane 来说,只接收带有电子邮件对象的“selected:email”事件作为有效负载并显示它要好得多。

    因此,在这种情况下,最好让每个邮箱选项卡 View 负责连接其特定 subview 实例及其模型和集合的事件。在我们的示例中,这意味着电子邮件 ListView 的特定实例及其集合和阅读 Pane View 的特定关联实例。

    总之,我建议每种情况都有用例,并且您应该尝试为遇到的每种情况明智地选择正确的方法。使用两者并学习看看什么适合哪种情况。

    最后,关于事件的可追溯性,您可以随时为 On 编写包装器。和 Off事件总线中的函数都调用正常 OnOff函数,但也向包含哪些对象绑定(bind)到哪些事件的寄存器添加/删除信息。您可以使用它进行调试并将有关这些对象的信息写入控制台,以便您可以在任何时间点清楚地了解事件总线及其监听器的状态。我从来没有想过这样做,但没有理由你不能;)

    帖子编辑 : tsiki 关于使用本地事件总线的评论是一个很好的评论。在上面的示例中,我使用了许多选项卡式邮箱,您可以为每个用户邮箱选项卡 View 使用本地事件总线。如果每个邮箱选项卡 View 本身变得非常复杂,包含许多嵌套的 subview 和大量要生成/处理的事件,您可能想要这样做。

    关于backbone.js - 我应该在backbone.js 中使用中央事件总线吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16874252/

    相关文章:

    javascript - 主干同步后 Collection View 中的触发功能

    javascript - HTML5如何获取被点击对象的id?

    c - 如何合并来自不同项目的事件循环

    javascript - 触发内部元素的点击事件

    javascript - Backbone.js 和嵌入式一对多关联

    backbone.js - Backbone EventAggregator 问题和问题

    javascript - Backbone Marionette 新架构与cdnJS

    javascript - 主干 _.each AJAX 依赖项

    jquery - 通过性能将事件处理程序附加到 jQuery 中的元素的最佳方法

    javascript - 将多个滤镜应用于对象的最佳方法