我试图避免以下问题的全局范围,但看不到避免它的方法。
我有一个名为“Application”的单例Javascript对象。这是一个AMD模块。
然后我有许多“模块”(不要与AMD模块混淆),这些模块只是我想在“应用程序”实例中注册的javascript对象。
例如:
require(['Application'], function(app) {
var module = {
name: "theme-switcher",
start: function() { console.log("started") } }
app.registerModule(module)
}
我想要的架构,我希望页面上的每个“模块”都可以使用“应用程序”实例注册自己。
这是一个棘手的部分:只有一个ALL模块已经注册到应用程序,我是否想要“应用程序”实例,循环遍历这些已注册的模块并调用它们的“Start()”方法。
我想这样做的方法就是在页面底部添加另一个需求块,如下所示:
<script type="text/javascript">
require(['Application'], function (app) {
// start all the registered modules running.
app.start(() => {
// this could be a call back function once all modules started..
});
});
Niavely想,这只是因为这需要呼叫是最后一次,它总是最后执行。但实际上,有时这会在上面的require调用之前被触发 - 所以Application会尝试Start()所有已注册的模块,然后模块本身都已经在应用程序中注册了自己。
无论我如何看待这个问题,我常常会回到这样一个事实:我需要在全球范围内保持一些状态,这样的事情:
第1单元:
var app = Application.Instance;
var moduleStart = function(){
require(['jquery'], function(jquery) {
// do module goodness here.
}};
app.registerModule({name: "theme-switcher", start: moduleStart })
//稍后在页面中 - 其他一些小部件 //模块2
var app = Application.Instance;
var moduleStart = function(){
require(['jquery'], function(jquery) {
// do second module goodness here.
}};
app.registerModule({name: "foo", start: moduleStart })
And then at the bottom of the page,
var app = Application.Instance;
app.Start(); // loops through registered modules calling start() method.
当然必须有办法避免全球范围吗?
我想要这样做的原因是,我希望“应用程序”管理页面上已注册模块的生命周期 - 包括启动/暂停/停止等等。我还希望应用程序发布一个一旦ALL模块启动就会发生事件 - 因为这时我通常会停止显示我的“加载”动画,并实际显示DOM - 因为模块通常会在其start()方法中操作DOM而我不想要页面在一切开始之前都可以看到。
答案 0 :(得分:1)
这样做。如果您想要一个 AMD模块的每个对象,我认为如果你还有RequireJS,我认为你应该这样做,那么你只需要一个字符串数组来定义那些AMD模块的名称。作为参数传递给应用程序的init。
Application.js: -
define(function (require, exports, module) {
"use strict";
var modules = {};
var moduleNames = [];
var numberOfModules = 0;
var loadedModules = 0;
exports.init = function (dependencies) {
numberOfModules = dependencies.length;
for (var i = 0; i < numberOfModules; i++){
var name = dependencies[i];
moduleNames.push(name);
require([name], function (moduleRef) {
loadedModules++;
modules[name] = moduleRef;
if (numberOfModules === loadedModules) {
exports.start();
}
});
}
};
exports.start = function () {
// all modules available
// use modules.myModuleName to access the module.
modules.myModuleName.functionName();
// or if they all have start() function and it needs calling
for (var i = 0; i < moduleNames.length; i++) {
modules[moduleNames[i]].start();
}
};
});
USAGE 根据您加载应用的方式,假设您在某处有应用参考,请致电:
// names of modules RequireJS uses to require, can be changed for each page.
var dependencies = ['moduleOne', 'moduleTwo', 'myModuleName'];
app.init(dependencies);
此代码的CodePen略有改动,可在一个页面上运行... http://codepen.io/owenayres/pen/MyMJYa