我正在尝试在 ExtJs/Javascript 中构建一个应用程序,并注意到事件是保持组件相互独立的好方法。但是,引发和捕获事件的方式使它们对调用者和接收者更加具体。
有没有更好的方法来做到这一点。我计划编写一个中心 EventBus 类,任何组件都可以使用该类引发一个事件,而另一个可以注册以收听它。
是否有任何图书馆已经可以实现这样的目标。我看到backbone.js 不确定它是否在做我正在寻找的事情。
我正在尝试在 ExtJs/Javascript 中构建一个应用程序,并注意到事件是保持组件相互独立的好方法。但是,引发和捕获事件的方式使它们对调用者和接收者更加具体。
有没有更好的方法来做到这一点。我计划编写一个中心 EventBus 类,任何组件都可以使用该类引发一个事件,而另一个可以注册以收听它。
是否有任何图书馆已经可以实现这样的目标。我看到backbone.js 不确定它是否在做我正在寻找的事情。
编写 aMediator
非常简单,如果您已经有了一个执行事件委托的框架,使用 a publisher/subscriber
orobserver
模型(无论它们被称为events
还是actions
他们将系统称为 anemitter
或其他)。
您只需制作Mediator
唯一的emitter
/ publisher
/etc,然后让您的模块/类/服务/等访问该Mediator
.
var myEvents = Mediator(),
Module1 = (function (events) {
var private_data = {},
private_method = function () {},
public_interface = { init : init };
function init () { // setup procedures
events.listen("widget/process/request", function (data) {
var result = doStuff(data);
events.fire("widget/process/result", result);
});
}
}(myEvents)),
Module2 = (function (events) {
var private_data = {},
public_interface = { init : init };
function init (data) { // setup procedures
events.fire("widget/process/request", data);
events.listen("widget/process/result", private_method);
}
return public_interface;
}(myEvents));
Module1.init();
Module2.init(data);
如果你愿意,你甚至可以在你的类中做一些事情,来包装你的中介,这样你就可以为你的“类”/模块拥有公共方法,这些方法看起来像它们自己的事件,但会传递数据给调解员:
var myClass = function () {
var mediator = null,
public_interface = {
fire : function (evt, data) { if (!mediator) { return; } mediator.fire(evt, data); },
listen : function (evt, handler) { if (!mediator) { return; } mediator.listen(evt, handler); },
setMediator : function (newMediator) { mediator = newMediator; }
}
};
var mediator = Mediator(),
obj1 = myClass(),
obj2 = myClass();
obj1.setMediator(mediator);
obj2.setMediator(mediator);
obj1.listen("event1", obj1.doStuff.bind(obj1));
obj2.fire("event1", obj2.data);
您的模块现在都可以访问一个单一的中介或您选择的任何多个中介... ...您可以为每个小部件提供自己的中介,其各个组件可以共享... ...另外让每个小部件访问系统范围的中介,因此虽然组件不能访问像 AJAX 或 DOM 这样的全局服务,但小部件本身可以。
通过在组件中提供接口,您可以使用公共包装调用巧妙地编程(在主进程中以更经典的方式,而不是 lambda/callback-heavy JS 方式),所以现在:
var imageLoader = ImageLoader();
imageLoader.setMediator(mediator);
img = imageLoader.load("myimg037");
imageLoader.fire("imageloader/imageloaded/myimg037", img);
或者,在您的项目中可能会出现类似的情况——imageLoader
对任何其他模块一无所知,但是当您调用它的.fire
方法时,任何共享同一个中介并监听该事件的模块都会收到通知。
查看 ozef Sakalos(又名 Saki)的 MsgBus 插件。
http://examples.extjs.eu/?ex=msgbus
它为 ExtJS 组件之间的消息传递提供了一个发布/订阅模型。
此功能已通过 extjs4.x 中的控制器实现。控制器是监听事件并对其采取行动的中心位置。此外,每个组件都有 fireEvent 方法来触发可以在控制器中再次监听的自定义事件。有关更多信息,请参阅文档:
http://docs.sencha.com/ext-js/4-1/#!/guide/application_architecture
和