如何定义模块并在 AMD 的 dojo 中使用它?
Posted
技术标签:
【中文标题】如何定义模块并在 AMD 的 dojo 中使用它?【英文标题】:How to define Module and use it in dojo with AMD? 【发布时间】:2013-06-25 05:22:57 【问题描述】:我正在维护和扩展 AMD 之前的旧项目。 我希望在应用程序中添加一个图表。为此,我创建了一个js文件如下:
define(["dojox/charting/Chart",...."dijit/Dialog","dojo/dom-construct"],
function (Chart)
function showDailyChart(data)
//code to show the chart in a dialog
return customModules.singleChart;
);
我已将此文件保存为/customModules/singleChart.js
在我的主 html 页面中,我已将其添加到包中,如下所示:
var dojoConfig = parseOnLoad: true,
packages: [....,"name":"customModules",
"location":location.pathname.replace(/\/[^/]+$/, "")+"/modules"
];
我要调用它的函数是 AMD 之前的函数。所以我这样称呼它:
dojo.require("customModules.singleChart");
.
.
.
customModules.singleChart.showDailyChart(data);
我可以看到 /customModules/singleChart.js
已加载到 Firebug 控制台以及 Net Tab 中。但是没有customModules.singleChart
对象。奇怪的是也没有错误。我已经在 Firebug 以及 Google Chrome 的开发者工具中对此进行了测试。
使用dojo.require
调用 AMD 模块的正确方法是什么?还是有更好的方法来做我需要的事情?
【问题讨论】:
【参考方案1】:要将您的小部件与 AMD 之前的代码一起使用,您需要使用 dojo/_base/define 声明您的模块,并让您的定义函数的第一个参数是点符号的模块 ID,如下所示:
define(["dojo/_base/declare","dojox/charting/Chart",...."dijit/Dialog","dojo/dom-construct"], function (declare, Chart)
return declare("customModules.singleChart", null,
showDailyChart: function(data)
//code to show the chart in a dialog
);
);
declare 函数的第二个参数是您继承自的类或类列表,在本例中为 null。
然后您可以通过使用“new”关键字实例化这个小部件来使用它。
var foo = new customModules.singleChart();
foo.showDailyChart(data);
...
如果你想要一个静态函数,你可以这样做:
define(["dojo/_base/declare","dojox/charting/Chart",...."dijit/Dialog","dojo/dom-construct"], function (declare, Chart)
var widget = declare("customModules.singleChart", null,
);
widget.showDailyChart = function(data)
//code to show the chart in a dialog
return widget;
);
然后你可以像这样使用它:
customModules.singleChart.showDailyChart(data);
更多细节在这里:http://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html#signature
【讨论】:
通过这段代码,我可以得到customModules.singleChart
对象,但它没有showDailyChart
函数。
您必须实例化小部件。在这种情况下,该函数不是静态的,它是一个实例函数。请参阅我的更新答案。【参考方案2】:
我不确定,但我认为您需要创建一个具有showDailyChart
属性的对象。
这样的事情可能会奏效:
define(["dojox/charting/Chart",...."dijit/Dialog","dojo/dom-construct"], function (Chart)
return
showDailyChart: function(data)
//code to show the chart in a dialog
);
通常你现在应该可以通过访问来使用你的模块了:
require(["myPackage/myModule"], function(myModule)
myModule.showDailyChart(myData);
);
或者使用遗留代码(提醒这将在 2.0 中消失)。
dojo.require("myPackage.myModule");
myPackage.myModule.showDailyChart(myData);
【讨论】:
【参考方案3】:dojo/_base/loader
模块是 Dojo 1.7+ 中负责处理dojo.require
调用的模块。当您使用旧的 dojo.require
方法加载 AMD 模块时,如果 config-publishRequireResult
has-rule 为真(默认情况下),则 AMD 模块返回的对象将自动使用提供的对象名称定义dojo.require
调用,只要那里不存在任何对象。来自 Dojo 1.9 源,loader.js:669-672
:
var result = doRequire(moduleName, omitModuleCheck);
if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined)
lang.setObject(moduleName, result);
如果由于这些条件之一不成立而这不起作用,您可以自己使用dojo/_base/lang.setObject
手动设置对象。按照 Philippe 的建议,使用 dojo/_base/declare
的三参数版本只会使 dojo/_base/declare
调用 setObject
本身。
【讨论】:
以上是关于如何定义模块并在 AMD 的 dojo 中使用它?的主要内容,如果未能解决你的问题,请参考以下文章
Worklight 6.1 和外部 dojolib,使用 AMD 加载自定义模块
如何在 post create dojo AMD 模块中调用按钮单击事件