假设我在一个页面上有两个组件,用户可以与其中一个组件交互,而另一个组件应该更新,如下所示:
component A | component B
|
- option 1 link | "stuff related to option 1"
- option 2 link |
现在,当我们单击选项 2 链接
时,我们希望更新组件 B。
MarionetteJS 使用(或将在下一个主要版本中使用)Backbone.Radio .
我想知道执行此操作的最佳方法。我想到了两件事:
1:在两个组件中使用相同的 channel
// 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:通过使用中介器进一步解耦,例如:组件应该只使用它们“自己的” channel 。
// 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 的存在。
最佳答案
我认为选项 2 不必要地复杂。
基本上,您是在问事件聚合器模式还是中介器模式在这里更合适。要记住的主要事情是它们都是紧耦合的解决方案。这在您的示例中很模糊,因为您在组件之后命名请求(“update:b
”)。这是耦合的根源,而不是您使用相同 channel 的事实。
更具体地说,如果组件 A 和组件 B 确实不需要彼此了解,那么它们的名称不应该成为 API(即请求名称)的一部分。该请求应该以应该完成的实际工作命名(也许是performUpdate
?),而不是以谁正在做的工作命名。
当然,出于组织或命名空间的目的使用不同的 channel 仍然可能有意义。调解器模式肯定有其用途(例如,如果您需要它拦截请求并以某种方式更改它们)。但是仅仅使用它来盲目地路由请求以避免耦合是没有意义的。
您可能会发现this article由《Marionette》的创作者撰写,很有趣,因为它讨论了同样的问题。
关于backbone.js - 用于组件间通信的 Backbone.Radio,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32225994/