0

我正在使用 Chris Imrie 的 RequireJS for ExpressionEngine 迭代,使我的所有字段类型都兼容。我不明白的一件事是如何调用 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,我在更改库时没有问题。

4

2 回答 2

6

有几件事要尝试:

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

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();
})
于 2012-11-09T13:05:23.893 回答
5

为上面的答案道歉,我想我现在明白你想要做什么了。基本上,您所指的库(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()
于 2012-11-09T16:45:33.253 回答