原文地址:http://dojotoolkit.org/documentation/tutorials/1.7/modules/
dojo现在支持在异步模块异步(AMD)定义中加入模块写入功能了,这使得代码更容易编写和调试。在这一节中,我们学习关于这个模块的使用,并探讨如何使用它。
概述
异步模块定义(AMD)格式是一种新的模块格式,只使用于1.7版本以上。它取代了dojo.provide, dojo.require, dojo.requireIf, dojo.requireAfterIf, dojo.platformRequire, and dojo.requireLocalization的这种写法。它提供了在模块的风格上许多的dojo改进,包括充分的异步操作,真正的包装可移植性,更好的依赖性管理和改善调试支持。它也是一个社区驱动的标准,这意味着模块写入的这种风格可用于任何其他适合AMD装载的模块。我们将给你演示怎样使用这个新的格式,以及强调一些对于旧风格新特性的优势。
介绍异步模块的定义
在讨论加载模块之前,我们先简单的介绍下模块是如何定义的。
如果你以前使用过dojo的1.6版本或更早的版本,你首先会发现最大的不同的地方是,新的模块定义看起来更像是文件的路径了。例如:以前的dojox.encoding.crypto.Blowfish 现在将写成dojox/encoding/crypto/Blowfish. 新的定义使你用起来更像是要处理文件路径。你可以使用"./"和"../"来相对引入在同一包下的其它模块。你甚至可以使用url来代替模块定义来加载模块。
在介绍完新特性后,现在我们就开始我们的教程了。
配置加载器
我们的dojo整体文件夹结构应该是和下面的一样
/ index.html js/ lib/ dojo/ dijit/ dojox/ my/ util/
第一步要做的就是设置加载为异步加载,也就是设置async属性为true
- <script data-dojo-config="async: true" src="js/lib/dojo/dojo.js"></script>
async的设置也可以是在dofoConfig对象里设置,但不管怎么做,这个设置必须是在加载dojo之前设置。如果这个被忽略了,他就会使用同步操作。
在异步的模式下,加载器只定义了两种函数。
request 用于加载模块
define 用于定义模块
这里就是与传统的加载器有一个鲜明的对比。以前是加载所有模块。现在是并不是那么做了。
下一步就是来配置我们要加载的模块了
- var dojoConfig = {
- baseUrl: "/js/",
- tlmSiblingOfDojo: false,
- packages: [
- { name: "dojo", location: "lib/dojo" },
- { name: "dijit", location: "lib/dijit" },
- { name: "dojox", location: "lib/dojox" },
- { name: "my", location: "my", main: "app" }
- ]
- };
在这个配置中,baseUrl被设定为本地目录,目录中包含了我们所有的JavaScript代码,tlmSiblingOfDojo被设定为false,避免混淆不清的行为习惯导致模块包装路径异常。最后是定义包列表,这里util没有被加到包里,虽然也访问util但使用器时对于加载的文件请求解析会有不同。
Packages
一般来说,包只是模块的集合。dojo,dijit,dojox都是包的实例。然而,不同的目录中的模块的简单集合,包还包含了一些额外的功能,这些功能显着增强了模块的可移植性和易于使用。
包有三个主要的配置选项。
name,是包的名字。
location 是包的位置,可以是相对路径的baseURL或绝对路径。
main 是一个可选参数,默认为“main”,如果有人试图要求加载模块,它可以用来发现加载正确的模块文件。例如,如果你尝试要求“dojo”,将装载的是实际的文件"/js/dojo/main.js"。既然我们已经为“我”包重写此属性,如果有人需要“my”,他们将载入“"/js/my/app.js"的。如果我们试图要求加载“util”,这是没有定义的包,装载机会尝试加载"/js/util.js".。
现在,我们已经正确配置加载器,让我们学习如何使用它,先来看require
Requiring 模块
最好的解释就是例子
- require([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin" ], function(declare, _WidgetBase, _TemplatedMixin){
- // "declare" holds the dojo declare function
- // "_WidgetBase" holds the dijit _WidgetBase constructor
- // "_TemplatedMixin" holds the dijit _TemplatedMixin constructor
- // Do whatever you want with these modules here.
- });
- require({
- baseUrl: "/js/",
- packages: [
- { name: "dojo", location: "//ajax.googleapis.com/ajax/libs/dojo/1.7.1/" },
- { name: "my", location: "my" }
- ]
- }, [ "my/app" ]);
- // in "my/_TemplatedWidget.js"
- define([ "dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin" ], function(declare, _WidgetBase, _TemplatedMixin){
- return declare([ _WidgetBase, _TemplatedMixin ], {});
- });
- dojo.provide("my._TemplatedWidget");
- dojo.require("dijit._WidgetBase");
- dojo.require("dijit._TemplatedMixin");
- dojo.declare("my._TemplatedWidget", [ dijit._WidgetBase, dijit._TemplatedMixin ], {});
- // in "my/nls/common.js"
- define({
- greeting: "Hello!",
- howAreYou: "How are you?"
- });
- var map16 = { dojo: "dojo16", dijit: "dijit16", dojox: "dojox16" },
- dojoConfig = {
- packages: [
- { name: "dojo16", location: "lib/dojo16", packageMap: map16 },
- { name: "dijit16", location: "lib/dijit16", packageMap: map16 },
- { name: "dojox16", location: "lib/dojox16", packageMap: map16 },
- { name: "my16", location: "my16", packageMap: map16 },
- { name: "dojo", location: "lib/dojo" },
- { name: "dijit", location: "lib/dijit" },
- { name: "dojox", location: "lib/dojox" },
- { name: "my", location: "my" }
- ]
- };
- var dojoConfig = {
- paths: {
- "my/debugger/engine": "my/debugger/realEngine",
- "my/debugger": "other/debugger"
- }
- };
- var dojoConfig = {
- aliases: [
- [ "text", "dojo/text" ],
- [ "dojo/text", "my/text" ],
- [ "i18n", "dojo/i18n" ],
- [ /.*\/env$/, "my/env" ]
- ]
- };
- // in "my/foo/blah.js"
- define([ "my/otherModule", "my/foo/bar" ], function(otherModule, bar){
- // …
- });
- // in "my/foo/blah.js"
- define([ "../otherModule", "./bar" ], function(otherModule, bar){
- // …
- });
- // in "my/debug.js"
- define([ "dojo/dom", "dojo/dom-construct", "dojo/on" ], function(dom, domConstruct, on){
- on(dom.byId("debugButton"), "click", function(evt){
- require([ "my/debug/console" ], function(console){
- domConstruct.place(console, document.body);
- });
- });
- });
- // in "my/debug.js"
- define([ "dojo/dom", "dojo/dom-construct", "dojo/on", "require" ], function(dom, domConstruct, on, require){
- on(dom.byId("debugButton"), "click", function(evt){
- require([ "./debug/console" ], function(console){
- domConstruct.place(console, document.body);
- });
- });
- });
- // in "my/Dialog.js"
- define([ "dojo/_base/declare", "dijit/Dialog", "dojo/text!./templates/Dialog.html" ], function(declare, Dialog, template){
- return declare(Dialog, {
- templateString: template // template contains the content of the file "my/templates/Dialog.html"
- });
- });
- dojo.provide("my.Dialog");
- dojo.require("dijit.Dialog");
- dojo.declare("my.Dialog", dijit.Dialog, {
- templateString: dojo.cache("my", "templates/Dialog.html")
- });
- // in "my/Dialog.js"
- define([ "dojo/_base/declare", "dijit/Dialog", "dojo/i18n!./nls/common"], function(declare, Dialog, i18n){
- return declare(Dialog, {
- title: i18n.dialogTitle
- });
- });
- dojo.provide("my.Dialog");
- dojo.require("dijit.Dialog");
- dojo.requireLocalization("my", "common");
- dojo.declare("my.Dialog", dijit.Dialog, {
- title: dojo.i18n.getLocalization("my", "common").dialogTitle
- });
- // in "my/events.js"
- define([ "dojo/dom", "dojo/has!dom-addeventlistener?./events/w3c:./events/ie" ], function(dom, events){
- // events is "my/events/w3c" if the "dom-addeventlistener" test was true, "my/events/ie" otherwise
- events.addEvent(dom.byId("foo"), "click", function(evt){
- console.log("Foo clicked!");
- });
- });
- dojo.requireIf(window.addEventListener, "my.events.w3c");
- dojo.requireIf(!window.addEventListener, "my.events.ie");
- my.events.addEvent(dom.byId("foo"), "click", function(evt){
- console.log("Foo clicked!");
- });
- // in my/loadRenderer.js
- define([ "dojo/load!./sniffRenderer" ], function (renderer) {
- // do something with renderer
- });
- // in my/sniffRenderer.js
- define([], function () {
- // returns an array of module identifiers to load;
- // the first module listed is the one returned by dojo/load
- return [ sniffModuleIdOfRenderer() ];
- });
- var module = sniffModuleIdOfRenderer();
- dojo.require(module);
- var renderer = dojo.getObject(module);
- // do something with renderer
- // in "my/app.js"
- define(["dojo/dom", "dojo/domReady!", function(dom){
- // This function does not execute until the DOM is ready
- dom.byId("someElement");
- });
- dojo.ready(function(){
- dojo.byId("someElement");
- });
- // in "my/a.js"
- define([ "b" ], function(b){
- var a = {};
- a.stuff = function(){
- return b.useStuff ? "stuff" : "things";
- };
- return a;
- });
- // in "my/b.js"
- define([ "a" ], function(a){
- return {
- useStuff: true
- };
- });
- // in "my/circularDependency.js"
- require([ "a" ], function(a){
- a.stuff(); // "things", not "stuff"
- });
- // in "my/a.js"
- define([ "b", "exports" ], function(b, exports){
- exports.stuff = function(){
- return b.useStuff ? "stuff" : "things";
- };
- return exports;
- });
- // in "my/b.js"
- define([ "a" ], function(a){
- return {
- useStuff: true
- };
- });
- // in "my/circularDependency.js"
- require([ "a" ], function(a){
- a.stuff(); // "stuff"
- });
- // in "my/legacyModule.js"
- dojo.provide("my.legacyModule");
- my.legacyModule = {
- isLegacy: true
- };
- # node.js:
- node path/to/dojo.js load=my/serverConfig load=my/app
- # rhino:
- java -jar rhino.jar path/to/dojo.js load=my/serverConfig load=my/app
- <script data-dojo-config="async: true" src="path/to/dojo.js"></script>
- <script>require(["my/serverConfig", "my/app"]);</script>