http://dojotoolkit.org/documentation/tutorials/1.10/modules/index.html

Dojo支持以异步模型定义(AMD)方式编写的模块,让会让你的程序更加易读和易调试。在本教程中,我们会解释AMD的基础知识以及如何使用AMD。

如果你以前是使用1.7版本一下,想把代码迁移过来,这个教程是很有用的。本教程专注于介绍AMD。

概述

异步模块定义(AMD)模式是在dojo1.7的时候引入dojo的。对比之前的模块定义模式,新的模式包含了完整的异步操作、真正的可移植包、更好的管理模式、改良后的调试支持等。AMD是一种社区标准,这就意味着你写的模块也可以加载到其他库的ADM加载器中。在本教程中我们介绍AMD,以及如何使用它。

什么是模块?

一个模块是指可以用一个引用访问的值。如果你想在一个模块上加载多个数据或函数,那必须是在一个对象上以属性形式展现。如果我们只是定义一个简单的值,例如var tinyModule = 'simple value',AMD模块对此来说是多余的,但却是有效的。模块开始的作用是把你的代码分解成一个个小的逻辑块,以便能够处理特定的功能。如果你想定义一个人,包含姓名、地址等属性,并具有事件,以及一些函数,那么如果使用模块定义就变得很有意义。在文件系统中,一个模块都以一个独立的文件存储。

怎么创建一个模块

With AMD, you create a module by registering it with the loader.

A quick aside here — loader? What's a loader? The loader is the code (yes, it's just JavaScript!) that handles the logic behind defining and loading modules. When you load dojo.js or require.js, you get an AMD loader. The loader defines functions for interacting with it - require and define..

The global function define allows you to register a module with the loader. Let's look at a few examples:

使用AMD中的加载器注册的方式可以创建一个模块。

这里引出了一个概念,加载器。什么是加载器?加载器是一段代码(只是javascript代码),在定义和加载模型后,处理逻辑。当你加载dojo.js或者requires.js时,你就得到了AMD加载器。加载器定义了require和define函数。

全局函数define函数可以让你使用加载器注册一个模块。请看下面的例子。

 define(5);

这是一个最简单但却有效的例子,注册的值是5。

 define({
library: 'dojo',
version: 1.10
});

做点更有意思的,通过上面的代码,我们定义了一个包含了两个属性的模块。

 define(function(){
var privateValue = 0;
return {
increment: function(){
privateValue++;
}, decrement: function(){
privateValue--;
}, getValue: function(){
return privateValue;
}
};
});

在这个例子中,我们通过Define定义了一个函数。该函数包含的子函数及数据都被加载器以模块的形式存储起来。代码在定义的时候,使用了闭包,这样可以定义的私有变量就不能为外部的代码访问到。但可以被模块内部的函数作为模块的属性返回和设置。

如何加载模块

For starters, we need to understand how modules are identified. In order to load a module, you need some way of identifying it. Similar to the module/package systems of other programming languages, an AMD module is identified by its path and file name. Let's save the code from the above example in a folder:

首先我们要了解模块如何被识别的。为了加载模块,我们先要了解如何标识模块。类似于其他编程语言,AMD也是通过路径和文件名标识模块。例如下面的代码:

 app/counter.js

Let's also add a loader (Dojo of course!) and an index.html - the entry-point for our application. This gives us the following file structure:

我们还需要我们的dojo以及index.html,index.html是我们程序的入口点。文件结构如下:

 /
index.html
/dojo/
/app/
counter.js

index.html页面的代码如下:

 <html>
<body>
<script src="dojo/dojo.js" data-dojo-config="async: true"></script>
<script>
require([
"app/counter"
], function(counter){
log(counter.getValue());
counter.increment();
log(counter.getValue());
counter.decrement();
log(counter.getValue());
});
</script>
</body>
</html>

让我们回顾一下,我们刚才都做了什么?

  1. 在app/counter.js,我们调用了define的加载器注册了一个模块。请注意,我们定义的这个模块是一个对象的引用,不是一个构造函数-这就意味着模型的每个功能都引用于同一个对象。一般来说模块返回构造函数,但有些情况下,也可以返回单例对象。
  2. 在文件系统中,我们的自定义的模型存储在Index.html文件同级目录下的一个文件夹下。AMD加载器(dojo.dojo.js)位于所在文件夹位于Index.html页面的同级目录下。在加载模块的时候,我们没有进行任何额外的配置,就能够加载了app/counter.js模块,并得到其返回的值。
  3. 在index.html页面中,我们调用了require加载"app/counter"模块。你可以通过require(["app/counter"])加载模块。如果里面的代码引用了其他模块,你不必要引用所有的模块。如果你想引用一个模型,需要提供回调函数。加载函数会确保引用的模块被加载,并且作为参数传递给回调函数。就像其他函数一样,你可以随意命名你的参数-参数命名时和模块的名称没有一点关系。但在参数命名时和模块名称一致是一种好的编码方式。

模块加载模块

我们之前的例子都是使用的define函数的简单用法。当一个应用使用很好的模块组织架构的时候,自然的会有很多模块相互依赖。define函数会自动的加载你的模块依赖的其他模块。在定义模块的值之前,就把该模块依赖的其他模块在define函数中罗列出来。

 define([
"dojo/_base/declare",
"dojo/dom",
"app/dateFormatter"
], function(declare, dom, dateFormatter){
return declare(null, {
showDate: function(id, date){
dom.byId(id).innerHTML = dateFormatter.format(date);
}
});
});

This example demonstrates some more typical features of AMD applications:

这个例子展示了更多的AMD应用特性。

  1. 多个依赖-dojo/dom和app/dateFormatter(假设我们定义了这个)都列入了依赖列表中。
  2. 返回了一个构造函数-为模块起一个适当的名字,例如app/DateManager。使用该模块的代码如下所示。
 require([
"app/DateManager"
], function(DateManager){
var dm = new DateManager();
dm.showDate('dateElementId', new Date());
});

在使用dojo开发之前,AMD是你必须熟悉的概念之一。declare是另外一个重要的函数,如果你还不熟悉dojo/_base/declare,下面可以看该教程。tutorial

使用插件

除了常规的模块之外,AMD加载器还会调用一个具有特殊特性的模块-插件。和加载普通模块相比,插件是用来扩展加载器新特性的。在模块后面加上特殊字符!,就可以标识该模块是作为插件请求的。!号后的数据直接传递给插件处理。通过一些例子我们可以看到这会让代码保持清洁。Dojo提供了几个默认的插件,分别是dojo/text, dojo/i18n, dojo/has and dojo/domReady,让我们看下这些插件怎么用。

dojo/Text

当需要从文件中加载字符串的时候,就会用到dojo/text。一旦调用一次,模块就会被缓存,这样会减少网络请求。html字符串加载就需要dojo/text模块。录入加载小部件的模板,请求模块的代码如下:

 // in "my/widget/NavBar.js"
define([
"dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/text!./templates/NavBar.html"
], function(declare, _WidgetBase, _TemplatedMixin, template){
return declare([_WidgetBase, _TemplatedMixin], {
// template contains the content of the file "my/widget/templates/NavBar.html"
templateString: template
});
});

dojo/i18n

dojo/i18n loads language resource bundles according to the web browser's user locale. Its usage looks like this:

dojo/i18n会根据浏览器用户所在地区的不同加载不同的语言资源。用法如下:

 // in "my/widget/Dialog.js"
define([
"dojo/_base/declare",
"dijit/Dialog",
"dojo/i18n!./nls/common"
], function(declare, Dialog, i18n){
return declare(Dialog, {
title: i18n.dialogTitle
});
});

关于如何使用i18n的更多信息参考internationalization tutorial

dojo/has

Dojo’s loader includes an implementation of the has.js feature detection API; the dojo/has plugin leverages this functionality for requiring modules conditionally. Its usage looks like this:

dojo加载器包含了使用has.js检测特性的API。dojo/has的插件特性可以用来检测加载模块的一些前置条件。代码如下所示:

 // 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(){
console.log("Foo clicked!");
});
});

dojo/domReady

dojo/domReady is the replacement for dojo.ready. It is a module that simply doesn’t resolve until the DOM is ready

dojo/domReady是代替dojo.ready的模块,该模块是监测DOM是否加载好。例子代码如下:

 // 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/domReady模块而已,并没有使用到它的特性。

总结

The basic understanding of AMD provided in this tutorial will get you started with Dojo development, but you will soon find yourself running into more complicated scenarios. Read the Advanced AMD Usage tutorial to learn how to deal with:

本教程提供了你AMD的基本用法。但你会发现你会陷入更复杂的场景之中。你可以看下Advanced AMD UsageAMD高级使用教程,用于解决这些问题。

  • 配置加载器,可以让加载器加载本地不同路径下的包以及不同的服务。
  • 创建轻便的模块包。
  • 加载同一个模块或库的不同版本。
  • 加载非AMD代码。

AMD模块介绍(翻译)的更多相关文章

  1. 大数据技术之_14_Oozie学习_Oozie 的简介+Oozie 的功能模块介绍+Oozie 的部署+Oozie 的使用案列

    第1章 Oozie 的简介第2章 Oozie 的功能模块介绍2.1 模块2.2 常用节点第3章 Oozie 的部署3.1 部署 Hadoop(CDH版本的)3.1.1 解压缩 CDH 版本的 hado ...

  2. Webpack - CommonJs & AMD 模块打包器

    Webpack 是一个 CommonJs & AMD 模块打包器.可以把你的 JavaScript 代码分离为多个包,在需要的时候进行加载,支持预处理文件,例如 json, jade, cof ...

  3. webkit模块介绍

    一.Webkit模块   用到的第三方库如下:   cairo 一个2D绘图库 casqt Unicode处理用的库,从QT中抽取部分代码形成的 expat 一个XML SAX解析器的库 freety ...

  4. 【液晶模块系列基础视频】1.2.iM_RGB模块介绍

    [液晶模块系列基础视频]1.2.iM_RGB模块介绍(上) [液晶模块系列基础视频]1.2.iM_RGB模块介绍(下) ============================== 技术论坛:http ...

  5. 【液晶模块系列基础视频】1.1.iHMI43模块介绍

    [液晶模块系列基础视频]1.1.iHMI43模块介绍(上) [液晶模块系列基础视频]1.1.iHMI43模块介绍(下) ============================== 技术论坛:http ...

  6. CSS3_概述、发展史、模块介绍、与浏览器之间的关系

    一.CSS3概述和CSS3的发展史: 1.css3概述: CSS3是CSS2的升级版本,3只是版本号,它在CSS2.1的基础上增加了很多强大的新功能.    目前主流浏览器chrome.safari. ...

  7. 嵌入式系统图形库GUI核心模块介绍

    本文转载自:http://blog.csdn.net/xteda/article/details/6575278 (作者 冯青华 信庭嵌入式工作室(www.xteda.com)- CEO Blog:h ...

  8. JavaScript AMD 模块加载器原理与实现

    关于前端模块化,玉伯在其博文 前端模块化开发的价值 中有论述,有兴趣的同学可以去阅读一下. 1. 模块加载器 模块加载器目前比较流行的有 Requirejs 和 Seajs.前者遵循 AMD规范,后者 ...

  9. IIS7 常用模块介绍说明

    1.1.0   IIS常用的功能模块介绍: 1)         静态内容:可发布静态 Web 文件格式,比如 HTML 页面和图像文件. 2)         默认文档:允许您配置当用户未在 URL ...

随机推荐

  1. mantis邮箱配置

    1.修改/var/www/html/mantisbt-1.3.3/config下config_inc.php配置文件 以163邮箱为例 # --- Email Configuration --- $g ...

  2. OD调试16

    今天还是15的那个程序,但是呢,换一种方法去掉NAG窗口 用OD载入,暂停,查看调用的堆栈 先看最后一个    查看调用,下断点 往上看看,找到入口的地方,设下断.点,重载,运行,单步 通过单步发现 ...

  3. Exchange 基本命令累计

    Get-ExchangeServer | fl name,edition,admindisplayversion  //查看exchange服务器版本

  4. Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path 解决办法

    返回数据解析错误 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT ...

  5. 救援linux

    挂载分区 mount /dev/sdaX /mnt/ 挂载其他 mount --bind /dev/ /mnt/dev/ mount --bind /proc/ /mnt/proc/ mount -- ...

  6. javascript常用数组算法总结

    1.数组去重 方法1: JavaScript //利用数组的indexOf方法 function unique (arr) { var result = []; for (var i = 0; i & ...

  7. Razor视图引擎-基础语法

    所有以 @开头 或 @{ /* 代码体 */ }  (在@与{直接不得添加任何空格) 的部分代码都会被ASP.NET引擎进行处理. 在 @{ /*代码体*/ } 内的代码每一行都必须以";& ...

  8. ASP.NET MVC中多种ActionResult用法总结

    最近一段时间做了个ASP.NET MVC4.0的项目,项目马上就要结束了,今天忙里偷闲简单总结一下心得: 1. 如果Action需要有返回值的话,必须是ActionResult的话,可以返回一个Emp ...

  9. 在RedHat上安装gcc,java 和 eclipse-rcp

    本文全是如何用rpm包在红帽子54上安装gcc,automake,java和eclipse等,不是源代码编译,请大家不要误会了. 其实通过rpm包安装东西很简单,麻烦的是有很多rpm是要根据顺序进行先 ...

  10. 手把手教你如何加入到github的开源世界!

    http://www.cnblogs.com/wenber/p/3630921.html 我曾经一直想加入到开源项目中,但是因为没有人指导流程,网上看了很多,基本都是说了个大概,如果你也是一个初出茅庐 ...