Backbone EventAggregator问题和问题

时间:2013-04-23 13:37:04

标签: backbone.js requirejs marionette eventaggregator

我正在构建一个Backbone应用程序,使用require.js进行模块化加载,使用Marionette来帮助我的应用程序结构和功能。我为事件聚合器设置了一个require模块,如下所示: -

define(['backbone', 'marionette'],function(Backbone, Marionette){
    var ea = new Backbone.Wreqr.EventAggregator();
    ea.on('all', function (e) { console.log("[EventAggregator] event: "+e);});
    return ea;
});

我希望将它传递给我的其他需求模块,并将其作为中央事件处理和消息传递组件,我正在取得一些成功。我可以将发布作为依赖项传递给其他模块,没有问题,如下所示: -

define(['marionette', 'text!templates/nav.html', 'shell/vent'], function (Marionette, text, vent) {
    return SplashView = Marionette.ItemView.extend({
        template : text,
        events : {
            'click #splashContinueButton': 'onButtonClick'
        },
        onButtonClick : function(evt) {
            vent.trigger('onSplashContinueClick'); 
        }
    });
});

我遇到的问题是,虽然所有事件都是在我的应用程序的不同位置触发(我可以在控制台日志中看到),但我无法在应用程序的某些部分收听它们。例如,我有一个Marionette模块(在运行时作为require模块加载),它试图获取一些这样的事件: -

var SplashModule = shellApp.module("SplashModule");
SplashModule.addInitializer(function(){
    vent.on("onSplashModelLoaded", this.onSplashModelLoaded);
    vent.on("onSplashContinueClick", this.onSplashContinueClick);
}

我什么都没得到,即使我从这个地方登录通风口我也可以看作是一个物体。在日志中,它包含一系列事件,这些事件实际上只包含根级应用程序正在侦听的事件,而不包含应用程序其他部分正在侦听的任何其他事件。这就是我的理解分崩离析的地方:我认为我可以将事件聚合器用作整个应用程序结构中的全局通信和消息传递系统。任何人都可以对可能发生的事情有所了解吗?

非常感谢,

萨姆

* 更新/编辑/解决方案 *

您好,我现在正在工作(发布上述内容后仅5分钟 - doh!)。基本上,在模块的初始化器事件中添加我的监听器太早了(据我所知)。我将它们沿着功能链进一步移动,现在一切都按预期运行。

2 个答案:

答案 0 :(得分:4)

为了让它正常工作,我必须做出的改变是我必须在模块中进一步删除“onSplashContinueClick”中的vent监听器。在此更改之前,它处于初始化函数中,但现在它更进一步: -

define(["backbone", "marionette", "shell/vent", "shell/shellapp", "shell/splash/splashmodel", "shell/splash/splashview"], function(Backbone, Marionette, vent, shellApp, SplashModel, SplashView){

var SplashModule = shellApp.module("SplashModule");

SplashModule.addInitializer(function(){
    trace("SplashModule.addInitializer()");
    SplashModule.model = SplashModel;
    SplashModule.model.fetch({
        success:function(){
            //trace("splashModel.fetch success")
            SplashModule.onSplashModelLoaded();
        },
        error:function() {
            //trace("splashModel.fetch error")
        }
    });

});
SplashModule.addFinalizer(function(){

});
SplashModule.initView = function () {
    //trace("SplashModule.initView()");
    SplashModule.mainView = new SplashView({model: SplashModel});
    shellApp.mainRegion.show(SplashModule.mainView);
    vent.on("onSplashContinueClick", this.onSplashContinueClick);

};
SplashModule.end = function () {
    trace("SplashModule.end()");
    shellApp.mainRegion.close();
    vent.trigger("onSplashModuleComplete");
};


// events
SplashModule.onSplashModelLoaded = function () {
    trace("SplashModule.onSplashModelLoaded");
    SplashModule.initView();
};
SplashModule.onSplashContinueClick = function () {
    trace("SplashModule.onSplashContinueClick()");
    SplashModule.end();
};


return SplashModule;
});

我猜这个问题与依赖关系何时可用和/或准备好的顺序有关。我相信在初始化方法期间,通风口还没有为听众做好准备。这可能与我在require模块中使用Marionette模块有关。

答案 1 :(得分:1)

使用 RequireJS 还涉及一些干净的模块...... Backbone.Wreqr.EventAggregator 是一个模块,是 Marionette.js 的一部分(为了记录,Derrick Bailey只是把这个模块放在他的图书馆里的其他人身上,同样的事情 Backbone.BabySitter ) 使用RequireJS,您只能看到库导出的内容,在本例中是Marionette 我认为最好的办法是将木偶分成3个模块,它实际上包含了backbone.babysitter,backbone.wreqr和marionette。 然后你必须为每个模块创建一个垫片

我用过这个

require.config({    
    baseUrl: "/Scripts/",        
    paths: {
     "json2": "vendor/JSON2",
     "backbone": "vendor/backbone/backbone.1.1.0",
     "localStorage": "vendor/backbone/backbone.localStorage.1.1.9",
     "marionette": "vendor/backbone/backbone.marionette.1.8.6",
     "bootstrap": "vendor/bootstrap/bootstrap.3.1.1",
     "jquery": "vendor/jquery/jquery.1.8.3",
     "text": "vendor/Require/text.0.27.0",
     "underscore": "vendor/underscore/underscore.1.5.2",
     "wreqr": "vendor/backbone/backbone.wreqr",
     "babysitter": "vendor/backbone/backbone.babysitter",
  },
  shim: {
     "json2": {
         exports: "JSON"
     },
     "jquery": {
        exports: "$"
     },
     "underscore": {
        exports: "_"
     },
     "bootstrap": {
        deps: ["jquery"]
     },
    "backbone": {
        deps: ["underscore", "jquery"],
        exports: "Backbone"
     },
     "validation": {
        deps: ["backbone"],
        exports: "Backbone.Validation"
     },
     "wreqr": {
        deps: ["backbone", "underscore"],
        exports: "Backbone.Wreqr"
     },
     "marionette": {
        deps: ["backbone", "babysitter", "wreqr"],
        exports: "Backbone.Marionette"
     },
     "localStorage": {
        deps: ["backbone"],
        exports: "Backbone.LocalStorage"
     }
 }
});

一旦你有了这个,你将能够使用wreqr 你写的是你脚本中的另一个技巧 define(['backbone', 'marionette'],function(Backbone, Marionette){ 有点令人不安,因为你永远不会知道在你的实现中使用Backbone或Marionette是否是故意的。我的意思是,与骨干和木偶有关的命名空间是Backbone和Marionette;我建议你将Backbone称为骨干,将Marionette称为牵线木偶,如下所示: define(['backbone', 'marionette'],function(backbone, marionette){。这样做,您将能够检查您的模块是否已根据RequireJS的要求下载。

然后,一旦创建了垫片,您的第一个块代码应该如下所示

define(["wreqr"],function(wreqr){
    var ea = new wreqr.EventAggregator();
    ea.on('all', function (e) { console.log("[EventAggregator] event: "+e);});
    return ea;
});