骨干/木偶事件聚合器 - 为什么这样的设计模式

时间:2014-07-23 21:00:20

标签: javascript events backbone.js marionette

在Backbone中,您可以创建自己的EventAggregator并将其绑定到您的app-object:

MyApp = {};
MyApp.vent = _.extend({}, Backbone.Events);

Marionette的作者Derick Bailey将这样的EventAggregator作为每个木偶应用程序的属性,可通过.vent获取(阅读更多here):

MyApp = new Backbone.Marionette.Application();

MyApp.vent.on("some:event", function(){
  alert("some event was fired!");
});

MyApp.vent.trigger("some:event");

事件聚合器是某种单身人士。没关系,每个应用程序一个经纪人就足够了。但我没有找到将此代理附加到应用程序对象的方便,因为系统中的其他对象与它通信并不舒服。许多应用程序依赖于RequireJS,当您创建视图或模型时,您必须将应用程序单例引用传递给它,以便能够侦听此代理发布的事件。我的问题是 - 为什么默认聚合器不能通过requirejs作为直接单例,例如

define([], function() {
  var Vent = _.extend({}, Backbone.Events);
  var myVent = new Vent();
  return myVent;
})

然后我们可以在项目的任何requirejs-module中要求这个并且具有相同的实例,而不需要手动传递vent作为构造函数参数(例如var model = new MyModel({vent: vent});)。或者另一种方法,甚至可能更好 - 为什么Marionette没有为所有创建的模型和视图注入应用程序的事件聚合器的引用,以便我们不必关心它?

总结一下,问题是:为什么建议将事件聚合器作为应用程序对象的属性,因为它迫使我们手动将对它的引用传递给它需要与之通信的每个对象?

顺便说一下,非常欢迎杰里米和德里克回答这个问题。我想这个设计很有意义,但我还看不到它。

1 个答案:

答案 0 :(得分:5)

你是对的,将全局事件聚合器从应用程序中挂起,在某些情况下很有用,但不是全部。

Marionette实际上正朝着使用"频道"的方向发展。限制发射事件的范围

见这里

https://github.com/jmeas/backbone.radio

詹姆斯史密斯就这个确切的话题做了很好的谈话 https://www.youtube.com/watch?v=2b1G3TdlQEU

还可以查看有关频道和Event Aggregator的文档 http://marionettejs.com/docs/marionette.application.html#the-global-channel

希望这有帮助,请随时加入我们https://gitter.im/marionettejs/backbone.marionette 聊天更多