0

我正在尝试在 ExtJs/Javascript 中构建一个应用程序,并注意到事件是保持组件相互独立的好方法。但是,引发和捕获事件的方式使它们对调用者和接收者更加具体。

有没有更好的方法来做到这一点。我计划编写一个中心 EventBus 类,任何组件都可以使用该类引发一个事件,而另一个可以注册以收听它。

是否有任何图书馆已经可以实现这样的目标。我看到backbone.js 不确定它是否在做我正在寻找的事情。

4

3 回答 3

2

编写 aMediator非常简单,如果您已经有了一个执行事件委托的框架,使用 a publisher/subscriberorobserver模型(无论它们被称为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方法时,任何共享同一个中介并监听该事件的模块都会收到通知。

于 2012-11-14T21:14:32.353 回答
1

查看 ozef Sakalos(又名 Saki)的 MsgBus 插件。

http://examples.extjs.eu/?ex=msgbus

它为 ExtJS 组件之间的消息传递提供了一个发布/订阅模型。

于 2012-11-14T21:22:37.307 回答
0

此功能已通过 extjs4.x 中的控制器实现。控制器是监听事件并对其采取行动的中心位置。此外,每个组件都有 fireEvent 方法来触发可以在控制器中再次监听的自定义事件。有关更多信息,请参阅文档:

http://docs.sencha.com/ext-js/4-1/#!/guide/application_architecture

http://docs.sencha.com/ext-js/4-1/#!/api/Ext.app.Controller

于 2012-11-14T22:32:53.123 回答