Backbone.Radio用于组件间通信

时间:2015-08-26 11:56:50

标签: backbone.js marionette messaging

假设我在页面上有两个组件,用户可以与一个组件进行交互,另一个组件应该更新,如下所示:

 component A       |   component B
                   |
 - option 1 link   |   "stuff related to option 1"
 - option 2 link   | 

现在,当我们点击option 2 link时,我们希望更新组件B.

MarionetteJS使用(或将在下一个主要版本中使用)Backbone.Radio

我想知道这样做的最佳方法。我想到了两件事:

1:在两个组件中使用相同的通道

// Component A
// ...
onOptionClick: function (evt) {
  Backbone.Radio.channel('AvsB').request('update:b', {id: this.model.get('id')});
}

// Component B
// ...
initialize: function () {
  Backbone.Radio.channel('AvsB').reply('update:b', function () {
    // update contents...
  }
}

2:通过使用中介来解耦甚至更多,例如:组件应该只使用他们的“自己的”频道。

// Component A
// ...
onOptionClick: function (evt) {
  Backbone.Radio.channel('compA').request('option:isUpdated', {id: this.model.get('id')});
}

// Mediator (eg. main.js, a controller, or whatever high-level object)
var channelCompA = Backbone.Radio.channel('compA');
var channelCompB = Backbone.Radio.channel('compB');
channelCompA.reply('option:isUpdated', channelCompB.request('content:shouldUpdate'));

// Component B
// ...
initialize: function () {
  Backbone.Radio.channel('compB').reply('content:shouldUpdate', function () {
    // update contents...
  }
}

选项2更多的工作,似乎有点不必要。但我真的不能感觉到选项1仍然过于具体。毕竟,组件A不应该关心组件B是否存在。

1 个答案:

答案 0 :(得分:3)

我认为选项2不必要地复杂化。

基本上,您在此处询问Event Aggregator模式或Mediator模式是否更合适。要记住的主要事情是它们是紧密耦合的两种解决方案。您的示例中隐藏了这一点,因为您在组件("update:b")之后命名请求。这是耦合的来源,而不是您使用相同频道的事实。

更具体地说,如果组件A和组件B确实不需要彼此了解,那么它们的名称不应该是作为请求名称的API的一部分。请求应该以应该完成的实际工作(performUpdate,或许?)来命名,而不是以谁来完成工作。

当然,为组织或命名空间使用不同的渠道仍然有意义。 Mediator模式肯定有其用途(例如,如果你需要它来拦截请求并以某种方式改变它们)。但是,使用它只是盲目地路由请求以避免耦合是没有意义的。

你可能会发现Marionette的创建者this article很有意思,因为它讨论了同样的问题。