如何获取定义requirejs主入口的<script>元素?</script>

时间:2013-11-04 09:16:10

标签: requirejs

我想传递一些requirejs的参数,如下所示:

<script src=".../require.min.js"
        data-main="..../config.js"
        data-modules="sticker datepicker">
</script>

这意味着我想在sticker

中加载datepickerconfig.js/main.js这样的模块
var modules = modules_parameters.split(' ');
_.each(modules, function (m) {
  var mod = require('...' + m);
  mod.init(); // Sticker.init(), DatePicker.init()
});

问题是如何获得modules_parameters

我现在可以像$('script[data-main]')一样使用jquery。但是,由于显然requirejs正在扫描data-main,它是否会公开api以访问相同的<script>代码?

背景

我有一个layout.html:<script src='require.js' data-main='config.js' data-modules='{placeholder}'>

和一个扩展它的page1.html:{placeholder}sticker datepicker{/placeholder}

和一个扩展它的page2.html:{placeholder}another another2{/placeholder}

以便每个页面加载自己的模块。

2 个答案:

答案 0 :(得分:1)

在RequireJS配置中,您可以添加config属性并定位运行初始化代码的模块:

require.config({
    ...
    config: {
        "app/config": {
            initModules: ["sticker", "datepicker"]
        }
    }
    ...
});

现在来自您的app/config模块:

define(["underscore", "module"], function(_, module) {
    var modules = module.config().initModules;
    _.each(modules, function (m) {
        // do your normal code here
    });
});

如果您不介意重新排列代码,此解决方案可以应对动态定义的initModules。我通常做的是将RequireJS配置与主模块分开。然后我有机会从内联脚本(通常用于语言首选项)自定义配置:

<script src="scripts/require-cfg.js"></script>
<script>
    require.config = require.config || {};
    // the array below is dynamically generated (i.e. JSP, PHP, etc)
    require.config["app/config"].initModules = ["sticker", "datepicker"];
</script>
<script src="scripts/lib/require.js"></script>
<script>
    // bootstrap the application
    require("app/main");
</script>

对于这种情况,require-cfg.js看起来不像:

var require = {
    paths: ...,
    shim: ...,
    config: ...
};

并不喜欢require.config({...});

答案 1 :(得分:0)

我在评论中建议将模块初始化作为模块实例化的一部分。 hbrlovehaku(原提问者)要求提供更多细节。评论过于拘束所以我在这里回答。

原始问题中的设计表明像“datepicker”这样的模块定义如下:

define(function () {
    function init() {
       // Initialize here.
    }
    return {
        init: init,
    }
});

那么使用上述模块的人必须这样做:

define(["datepicker"], function (datepicker) {
     datepicker.init();
});

那是因为模块实例化和模块初始化是分离的。但是,它们并非必须如此。该模块可以这样定义:

define(function () {
    // Initialize here
});

通过上述设计,只要另一个模块需要,模块就会被初始化。请注意,传递给define的函数在模块需要“datepicker”之前不会执行。所以使用“datepicker”的模块可以是这样的:

define(["datepicker"], function (datepicker) {
     // There is no need to call init.
});

然后页面可能包含以下内容:

<script src="[...]/require.min.js" data-main="[...]/config.js"></script>
<script>
    (function () {
        var mods = "{placeholder}".split(" ");
        // I don' know whether the anonymous function is necessary in the next line.
        require(mods, function () {});
    )();
</script>

实际上,即使需要初始化功能,上面的这个小片段也可以使用。像这样:

<script src="[...]/require.min.js" data-main="[...]/config.js"></script>
<script>
    (function () {
        var mods = "{placeholder}".split(" ");
        require(mods, function () {
            Array.prototype.forEach.call(arguments, function (mod) {
                mod.init();
            });
        });
    )();
</script>

{placeholder}只需要替换为实际的模块名称,就像在data-modules="{placeholder}"

中一样