2

我正在编写一个小应用程序(initApp.js, initApp.routinj.js, initApp.controller.js),需要使用 requires 加载模块。
这是我的代码(*)。
在每个模块中使用console.log我看到模块的加载顺序如下:

1) initController 
2) initRouting 
3) initApp 

这是正确的顺序吗?

现在另一个问题。
initApp.controller.js我需要访问initHeaderinitSidebar(在中定义initApp.js)之类的函数。
但正如您从我的代码 ( initApp.controller.js) 中看到的,console.log('initController', app);返回undefined.
为了解决这个问题,我getAppinitApp.controller.js.
但可以肯定的是,有更好的方法来完成这项任务。
任何的想法?
谢谢

(*)


** main.js **

define([
    'js/app',
    'js/init/initApp',
//    'js/tasks/tasksApp'
],
function (App)
{
    "use strict";
    App.initialize();
});

** initApp.js **

/*global define*/
define([
    'backbone',
    'js/app',
    'js/init/initApp.routing',
    'js/init/views/sidebarView',
    'js/init/views/headerView',
],
function (Backbone, App, Router, SidebarView, HeaderView)
{
    "use strict";
    console.log('initApp', Router)
    var initApp = new Backbone.Marionette.Application({

        initHeader: function ()
        {
            var headerView = new HeaderView();
            App.header.show(headerView);
        },

        initSidebar: function ()
        {
            var sidebarView = new SidebarView();
            App.sidebar.show(sidebarView);
        }

    });

    return initApp;
});

** initApp.routine,js **

/*global define*/
define([
    'backbone',
    'marionette',
    'js/init/initApp.controller'
],
function(Backbone, Marionette, controller)
{
    "use strict";
    console.log('initRouting', controller)
    var Router = Backbone.Marionette.AppRouter.extend({

        appRoutes: {
            '*defaults': 'index'
        }

    });
    return new Router({
        controller: controller
    });

});

** initApp.controller.js **

/*global define*/
define([
    'js/init/initApp'
],
function(app)
{
    "use strict";
    console.log('initController', app); // undefined
    var getApp = function () {
        var initApp;
        require(['js/init/initApp'], function (app) {
            initApp = app;
        });
        return initApp;
    };

    var controller = {
        index: function ()
        {
            var app = getApp();
            app.initHeader();
            app.initSidebar();
        }
    }

    return controller;

});
4

2 回答 2

2

不确定这是否是实现事物的正确方法,但在您的情况下,如果您按此顺序加载模块,它将起作用。

1) initApp
2) initController
3) initRouting

所以这意味着你main.js应该是:

define([
    'js/app',
    'js/init/initApp.routing'
],
function (App)
{
    "use strict";
    App.initialize();
});
于 2012-06-17T09:35:22.187 回答
1

您的文件中有一个循环依赖项:initApp -> initApp.routing -> initApp.controller -> initApp. 这就是你得到undefined.

在声明时,当您定义您的类/对象时,顺序仅在您的代码中存在依赖关系时才重要。在我的例子中,我在 initApp.js 中初始化了路由器和控制器,所以我有:

initApp.js

define(['backbone', 'js/init/initController', 'js/init/initApp.initRouting', ...],
function(Backbone, controller, Router, ...) {
  return {
    initialize: function() {
      // Store a namespaced global reference to my app.
      window.MyApp = new Backbone.Marionette.Application();
      MyApp.addRegions({...});
      MyApp.addInitializers(function(options) {
        MyApp.router =  new Router({controller: controller});
        // Other init stuff...
      });
      MyApp.start();
    }
  };
});

由于我在 window.MyApp 中存储了对我的应用程序的引用,因此现在可以在我的 JS 文件中访问它,而无需任何额外的逻辑。例如,我可以直接从控制器或任何视图访问区域:

MyApp.myRegion.show(someView);

所以我的 main.js 非常小:

require(['app', 'backbone', 'json2'], function(app){
  window.console = window.console || {log: function() {}}; // Needed for IE.
  app.initialize();
});

我的路由器或控制器 JS 文件都不相互依赖,也不依赖于 App 文件。

initApp.Routing.js

define([
  'jquery',
  'underscore',
  'backbone'
  ], function($, _, Backbone) {
  var Router = Backbone.Marionette.AppRouter.extend({
    appRoutes: {
      // My routes go here...
    }
  });
  return Router;
});

也就是我在App中初始化了我的路由,减少了JS文件之间的依赖。

同样,我的控制器仅向下依赖各种视图和集合:

initApp.Routing.js

define([
  'jquery',
  'underscore',
  'backbone',
  'myview',
  'mycollection'
  ], function($, _, Backbone, View, Collection) {
  var controller = {
    showMyView: function() {
      // ...
    }
  });
  return controller;
});

我花了一段时间才明白声明和执行之间的区别。只要您只在 JS 文件中声明内容(即包装在对象中,或调用扩展),我就有一个通过您的 main.js' 执行的单一入口点app.initialize(),您将是安全的,您可以MyApp在任何地方访问对象.

更新

有关在其他 JS 文件中访问您的应用程序实例的替代方法,请参阅更新后的 Backbone.Marionette wiki 上的从其他模块访问您的应用程序实例

于 2012-06-19T02:40:21.357 回答