Amd,requirejs - 想要确保总是最后执行的东西

时间:2016-05-19 12:38:05

标签: javascript requirejs single-page-application

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

我有一个名为“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而我不想要页面在一切开始之前都可以看到。

1 个答案:

答案 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