【问题标题】:How to access defined functions using RequireJS如何使用 RequireJS 访问定义的函数
【发布时间】:2012-11-09 00:47:48
【问题描述】:

我正在使用 Chris Imrie 的 ExpressionEngine RequireJS 迭代,使我的所有字段类型都兼容。我不明白的一件事是如何调用RequireJS中定义的函数。

https://github.com/ckimrie/RequireJS-for-EE

这是我正在尝试做的一个基本示例......

var loadImage = function() {
    console.log('loaded');
}

define(function () {
    return loadImage;
});

我如何实际访问 loadImage 函数?我的代码 100% 工作,但是当我开始使用 RequireJS 时,库的行为不同。下面是我正在使用的库中的一个 sn-p,它完全是为 RequireJS 分叉的。如果我删除 fork 并使用标准 jQuery 调用,它可以正常工作(即使 RequireJS 加载所有脚本)。

不起作用:

if (typeof define === 'function' && define.amd) {
    define(function () {
        return loadImage;
    });
} else {
    $.loadImage = loadImage;
}

有效

$.loadImage = loadImage;

为什么 jQuery 库会像这样 fork 代码?我担心我忽略了一些简单的事情,但考虑到所有这些代码都使用 ExpressionEngine Fieldtypes 的上下文,我在更改库时没有问题。

【问题讨论】:

    标签: jquery requirejs expressionengine


    【解决方案1】:

    有几件事可以尝试:

    您的定义函数需要有一个数组作为第一个参数,因为这是您指定此模块的任何模块依赖项的地方。如果您的模块不需要任何其他脚本或模块即可工作,则此数组为空,如下所示:

    define([], function(){
        //Your code here
    });
    

    现在这是稍微令人困惑的部分,因为 RequireJS 的工作方式是它使用模块路径作为模块名称。这真的很强大,因为它使您的模块具有高度的可移植性,而且还使指定您需要的模块及其所在位置的行为变得相同。

    因此,如果上面定义的模块位于“mymodule/js/component.js”,您将能够加载它并在另一个脚本中异步使用它,如下所示:

    //some existing script that then needs a JS module that has not been loaded yet
    require(['mymodule/js/component'], function(component){
       //All loaded modules are provided as arguments in the 
       //order they are specified in the require array
       var a = component();
    });
    

    所以你的例子变成了以下:

    //This script located at mymodule/js/loadImage.js
    if (typeof define === 'function' && define.amd) {
        define([], function () {
            return loadImage;
        });
    } else {
        $.loadImage = loadImage;
    }
    
    //Script located in another file that needs the loadImage module
    require(['mymodule/js/loadImage'], function(loadImage){
        loadImage();
    });
    

    最后一点,如果您愿意,可以通过将名称指定为 define 调用的第一个参数,为您的模块提供简短的、简洁的名称。这不是推荐的,因为您需要在第一次需要它时指定文件的路径,因为 RequireJS 不会仅从一个短名称中知道它的位置。适合的地方是当您预先加载所有脚本而不是在需要它们时(建议这样做,因为一切都是按需加载的)。但是,这里是您如何为模块指定“短”名称的方式:

    //This script located at mymodule/js/loadImage.js
    if (typeof define === 'function' && define.amd) {
        define("loadImage", [], function () {
            return loadImage;
        });
    } else {
        $.loadImage = loadImage;
    }
    

    如果您知道 loadImage 模块已加载,则上述技术允许您执行以下操作:

    //Even if loadImage has been already fetched, this is good practice since you can
    //add more modules to be the dependency array if you need
    require(['loadImage'], function(loadImage){
        loadImage();
    });
    //or sometimes this can be convenient:
    var loadImage = require("loadImage")
    loadImage();
    

    更新

    忘了提一下,如果您想创建一个需要 loadImage 模块才能运行的模块,您可以这样做:

    //By providing the module dependencies in the first argument, RequireJS will
    //fetch it and load it if needed
    define(['mymodule/js/loadImage'], function(loadImage){
        loadImage();
    })
    

    【讨论】:

    • 所有这些都是有道理的,并且是正确的答案。令我困惑的一件事是我发布了来自特定库的代码。我只是想知道人们如何在 RequireJS 的上下文中使用该库而不更改库的代码。这是有问题的特定库:github.com/blueimp/JavaScript-Load-Image。同样,我所有的代码都经过了一些小的调整,主要是想知道如何在没有调整的情况下让它工作(如果可能的话)。
    【解决方案2】:

    对上面的答案道歉,我想我现在明白你想要做什么了。基本上,您所指的库(Javascript-Load-Image)已经在他们的库中实现了 AMD 支持(您所指的定义函数),您希望在自己的脚本中使用它?

    RequireJS 有时会让人感到困惑,因为它能够加载普通脚本,也能够加载 AMD JS 模块。如果您有一个包含 JS 构造函数或函数的 JS 文件,您希望将其作为模块提供给代码的其他部分使用,它就像添加上面提到的 define() 调用一样简单。重要的部分是您需要确保 RequireJS 作为 AMD 模块请求它,否则它不会有模块名称。这就像省略“.js”一样简单。

    如上例:

    //In your script that needs the loadimage library you would load it by 
    //specifying the path to the JS file and omitting the ".js" extension
    require(["path/to/loadimage"], function(loadimage){
        loadimage();
    });
    
    
    //If you KNOW that the library has already been loaded by RequireJS
    //you can fetch it synchronously from RequireJS' memory by specifying 
    //its path without the .js
    var loadimage = require("path/to/loadimage");
    loadimage()
    

    【讨论】:

    • 看来我在 Theme Loader 中还有很多工作要做,才能让它支持所有这些随意的东西。
    • 一点也不,主题加载器可以完美运行。只要基本 URL 正确,剩下的就交给 RequireJS。
    猜你喜欢
    • 2013-06-26
    • 2013-05-09
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多