我正在编写一个小应用程序(initApp.js
,initApp.routinj.js
,initApp.controller.js
)需要使用require加载哪些模块。
这是我的代码(*)。
在每个模块中使用console.log
,我看到模块加载的顺序如下:
1) initController
2) initRouting
3) initApp
这是正确的顺序吗?
现在另一个问题。
在initApp.controller.js
我需要访问initHeader
和initSidebar
(在initApp.js
中定义)这样的功能。
但正如您从我的代码(initApp.controller.js
)中看到的那样,console.log('initController', app);
会返回undefined
为了解决这个问题,我在getApp
中定义了函数initApp.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.routin,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;
});
答案 0 :(得分:2)
不确定它是否是正确的实现方式,但是,在您的情况下,如果按此顺序加载模块,它将起作用。
1) initApp
2) initController
3) initRouting
所以这意味着你的main.js
应该是:
define([
'js/app',
'js/init/initApp.routing'
],
function (App)
{
"use strict";
App.initialize();
});
答案 1 :(得分: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文件中声明东西(即,包装在对象中,或者调用extend),我就可以通过你的main.js'app.initialize()
执行一个入口点,你将是安全的,你可以在任何地方访问MyApp
个对象。
<强>更新强>
有关在其他JS文件中获取对应用程序实例的访问权的替代方法,请参阅Access Your Application Instance From Other Modules上更新的Backbone.Marionette wiki。