Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Amd,requirejs-想要确保某些东西总是最后执行吗_Javascript_Requirejs_Single Page Application - Fatal编程技术网

Javascript Amd,requirejs-想要确保某些东西总是最后执行吗

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

我试图避免以下问题的全局范围,但无法找到避免它的方法

我有一个名为“Application”的单例Javascript对象。这是一个AMD模块

然后,我有许多“模块”(不要与AMD模块混淆),它们只是javascript对象,我想向“应用程序”实例注册

例如:

 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);