I am maintaining and extending an old project which was pre-AMD.
I wish to add an Chart to the application. for this, I have created a js file as follows:
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;
});
I have saved this file as /customModules/singleChart.js
In My main HTML Page, I have added it to the packages as follows:
var dojoConfig = { parseOnLoad: true,
packages: [....,{"name":"customModules",
"location":location.pathname.replace(/\/[^/]+$/, "")+"/modules" }
]};
The function from which I want to call it, is pre-AMD. So I am calling it as follows:
dojo.require("customModules.singleChart");
.
.
.
customModules.singleChart.showDailyChart(data);
I can see that /customModules/singleChart.js
is loaded in the Firebug console as well as Net Tab. However there is no customModules.singleChart
object. Strangely enough there is no error either. I have tested this in Firebug, as well as Google Chrome's developer tools.
What is the correct way to call an AMD Module using dojo.require
? Or is there a better way to do what I need?
To use your widget with pre-AMD code, you need to declare your module using dojo/_base/define, and have the first argument of your define function be the module ID in dot notation, like this :
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
}
});
});
The second argument to the declare function is the class or list of classes you inherit from, or null in this case.
You can then use this widget by instantiating it with the "new" keyword.
var foo = new customModules.singleChart();
foo.showDailyChart(data);
...
If instead you want a static function, you can do it like this :
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;
});
You can then use it like this :
customModules.singleChart.showDailyChart(data);
More details here : http://dojotoolkit.org/reference-guide/1.9/dojo/_base/declare.html#signature
I'm not sure but I think you need to create an object with a showDailyChart
property.
Something like this might work:
define(["dojox/charting/Chart",...."dijit/Dialog","dojo/dom-construct"], function (Chart) {
return {
showDailyChart: function(data){
//code to show the chart in a dialog
}
}
});
Normally you should be able to use your module now by accessing:
require(["myPackage/myModule"], function(myModule) {
myModule.showDailyChart(myData);
});
Or with the legacy code (remind that this will disappear in 2.0).
dojo.require("myPackage.myModule");
myPackage.myModule.showDailyChart(myData);
The dojo/_base/loader
module is the one which is responsible for handling dojo.require
calls in Dojo 1.7+. When you load an AMD module using the legacy dojo.require
method, if the config-publishRequireResult
has-rule is truthy (it is, by default), then the object returned by the AMD module will automatically be defined using the object name provided in the dojo.require
call as long as no object already exists there. From the Dojo 1.9 source, loader.js:669-672
:
var result = doRequire(moduleName, omitModuleCheck);
if(has("config-publishRequireResult") && !lang.exists(moduleName) && result!==undefined){
lang.setObject(moduleName, result);
}
If this is not working because one of these conditions is not true, you can manually set the object using dojo/_base/lang.setObject
yourself. Using the three-argument version of dojo/_base/declare
as suggested by Philippe just makes dojo/_base/declare
call setObject
itself.