我是一名ActionScript 3开发人员,他正在构建一个大型JavaScript应用程序。 所以我理解模块并理解AMD是一个很好用的模式。我读了一下RequireJS并实现了它。但是,我仍然不明白的是如何实现跨模块通信。我明白应该有某种调解员...... 我阅读文章和帖子,仍然无法理解如何简单地实现它。 这是我的代码,简化:
main.js
require(["Player", "AssetsManager"], function (player, manager) {
player.loadXML();
});
Player.js
define(function () {
function parseXml(xml)
{
// NOW HERE IS THE PROBLEM -- how do I call AssetsManager from here???
AssetsManager.queueDownload($(xml).find("prop").text());
}
return {
loadXML: function () {
//FUNCTION TO LOAD THE XML HERE, WHEN LOADED CALL parseXml(xml)
}
}
});
AssetsManager.js
define(function () {
var arrDownloadQueue = [];
return {
queueDownload: function(path) {
arrDownloadQueue.push(path);
}
}
});
任何“为傻瓜”帮助将不胜感激:) 谢谢。
答案 0 :(得分:1)
要从define()
的其他模块加载模块,您只需将第一个参数设置为数组,并在其中包含模块名称。我们可以说,在您的代码中,您希望将Player.js
加载到AssetsManager.js
,您只需在数组中包含字符串Player
。
这是可能的,因为define
的抽象实现等同于require
,只是传递给define
的回调期望返回一个值,并且它将添加一个“模块”到您可以加载的依赖项列表。
<强> AssetsManager.js 强>
define(['Player'], function (player) {
//... Your code.
});
但是,如果我可以添加它,我个人更喜欢在传递给require
的回调中使用define
来获取要加载的依赖项,而不是将参数传递给回调。
所以这是我的建议:
define(['Player'], function () {
var player = require('Player');
});
这是因为它更符合CommonJS。
这就是main.js
格式化为更适合CommonJS的方式:
require(["Player", "AssetsManager"], function () {
var player = require('Player');
var manager = require('AssetsManager');
player.loadXML();
});
但CommonJS的做事方式只是个人偏好。我的理由是,您在数组中输入依赖项名称的顺序可能随时发生变化,我不希望必须同时遍历数组和参数列表。
我的另一个理由(虽然,它只是迂腐),是我来自Node.js的世界,其中模块通过require()
加载。
但这取决于你。
答案 1 :(得分:0)
(这将是对skizeey答案的回复,但我没有足够的声誉)
在不通过require引入Player的AssetManager依赖性的情况下解决此问题的另一种方法是传递main.js已经存在的AssetManager实例。实现此目的的一种方法可能是使Player的loadXML函数接受一个AssetManager参数,然后将该参数传递给parseXml,然后parseXml使用它。另一种方法可能是Player有一个变量来保存一个由parseXml读取的AssetManager。它可以直接设置,也可以使用在变量中存储AssetManager的函数,称为setAssetManager。后一种方法有一个额外的考虑因素 - 然后你需要处理在调用loadXml之前未设置该变量的情况。这个概念通常被称为“依赖注入”。
要明确我不建议使用AMD加载它。我只是想为您提供更多选择;也许这种技术在解决另一个问题时可能会让你更方便,或者可能会帮助别人。 :)