如何使用RequireJS访问已定义的函数

时间:2012-11-09 00:47:48

标签: jquery requirejs expressionengine

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

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

这是我想要做的一个基本例子......

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

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

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

不起作用:

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

工作

$.loadImage = loadImage;

为什么jQuery库会像这样分叉代码?我担心我忽略了一些简单的事情,但鉴于所有这些代码都与ExpressionEngine Fieldtypes有关,我没有问题改变库。

2 个答案:

答案 0 :(得分:6)

要尝试的一些事项:

您的define函数需要有一个数组作为第一个参数,因为您可以在此指定此模块的任何模块依赖项。如果您的模块不需要任何其他脚本或模块,那么此数组将保持为空,如下所示:

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

答案 1 :(得分:5)

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

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