如何定义模块并在 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 中使用它?的主要内容,如果未能解决你的问题,请参考以下文章

如何从AMD dojo创建构建

Worklight 6.1 和外部 dojolib,使用 AMD 加载自定义模块

如何在 post create dojo AMD 模块中调用按钮单击事件

原创(AMD)JavaScript模块化开发(dojo)

是否可以通过 dojo 的 AMD 加载器向 dojo 模块请求添加请求参数

什么是AMD规范