Javascript Amd,requirejs-想要确保某些东西总是最后执行吗
我试图避免以下问题的全局范围,但无法找到避免它的方法 我有一个名为“Application”的单例Javascript对象。这是一个AMD模块 然后,我有许多“模块”(不要与AMD模块混淆),它们只是javascript对象,我想向“应用程序”实例注册 例如:Javascript Amd,requirejs-想要确保某些东西总是最后执行吗,javascript,requirejs,single-page-application,Javascript,Requirejs,Single Page Application,我试图避免以下问题的全局范围,但无法找到避免它的方法 我有一个名为“Application”的单例Javascript对象。这是一个AMD模块 然后,我有许多“模块”(不要与AMD模块混淆),它们只是javascript对象,我想向“应用程序”实例注册 例如: require(['Application'], function(app) { var module = { name: "theme-switcher", start
require(['Application'], function(app) {
var module = {
name: "theme-switcher",
start: function() { console.log("started") } }
app.registerModule(module)
}
我要介绍的体系结构是,我希望页面上的每个“模块”都向“应用程序”实例注册自己
这里是棘手的部分:只有在所有模块都注册到应用程序之后,我才希望“应用程序”实例在这些注册的模块中循环并调用它们的“Start()”方法
我认为这样做的方式是在页面底部添加另一个require块,如下所示:
<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..
});
});
//稍后在第页-其他一些小部件
//单元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.
当然,必须有一种避免全球范围的方法来做到这一点
我之所以想这样做,是因为我希望“应用程序”管理页面上注册模块的生命周期,包括启动/暂停/停止模块等。我还希望应用程序在所有模块启动后发布事件,因为此时我通常会停止显示“加载”动画,并实际显示DOM—因为模块通常会在其start()方法中操作DOM,我不希望页面在启动之前可见。这样就可以了。如果你让你想要的每个对象都有一个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();
}
};
});
这段代码的代码笔,稍微修改一下,可以在一页上工作 为什么你不希望你的“模块”是RequireJS AMD模块?我对此感到困惑。如果我的模块被定义为requireJS AMD模块,我仍然需要()它们,并在应用程序实例中注册它们-那么这如何帮助我解决问题呢?即使他们将“应用程序”视为依赖项,我如何确保在调用“Application.Start()”之前,我的所有模块都已在应用程序中注册。我还考虑了反转依赖项,即应用程序AMD模块可以“依赖”我的所有模块。但是,我想避免这种情况,因为每页的列表都会不同,并且会不断变化。此外,我还希望允许在页面中动态添加/删除模块,因此我确实需要允许在应用程序实例中注册/注销模块,而不是使用任何硬编码的依赖项。谢谢,这是反转依赖项的想法,因此,而不是模块-->应用程序,应用程序-->所有模块。我认为这可能是正确的方向,但我的问题是,我希望开发人员能够开发并向页面添加新模块,并提供一些API,以便他们可以在应用程序依赖项列表中包含/注册他们的模块。我将对此进行更深入的探讨,也许我可以使用垫片依赖项来实现这一点?或者我需要依赖项列表在全局范围内,以便他们可以向其中添加模块。@Darrell您可以将上述内容转换为API。只需创建一个名为moduleService.js的新模块,并利用它注册模块并将其附加到我的示例中使用的对象/数组中。此答案中显示的代码不起作用。除了在任何地方都没有初始化
mymodule
这一老生常谈的问题外,调用require
(如此处代码所示)将导致失败。有关技术详细信息,请参阅。要让RequireJS执行CommonJS sugar所需的转换(您正在使用的),必须使用字符串文本执行require
调用。它不能是变量<代码>要求(“foo”)可以<代码>var foo=“foo”;要求(foo)代码>不好。如果您碰巧已经在其他地方加载了模块,require
调用不会失败,但这是运气使然,而不是设计使然。这是导致间歇性加载问题的途径,而不是稳定的代码库。我们得出的结论是,对于我的用例,我希望页面的模块列表是可配置的,将此信息(页面上的模块列表)存储在后端数据库中是有意义的,然后在页面加载时,从数据库中获取此列表。标记为asnwer
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();
}
};
});
// names of modules RequireJS uses to require, can be changed for each page.
var dependencies = ['moduleOne', 'moduleTwo', 'myModuleName'];
app.init(dependencies);