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. [转载 ]POJ 1273 最大流模板

    转载 百度文库花了5分下的 不过确实是自己需要的东西经典的最大流题POJ1273 ——其他练习题 POJ3436 . 题意描述: 现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条水渠,给 ...

  2. Cruehead.1

    查壳   没有 我拖 alt+F9 到上面        入口处   下断 关键跳      略过   就没了 要实现 强暴  直接过... 仔细来看看... 那两个调用   都下断   看看  判断 ...

  3. tensorflow资料补充(很棒)

    http://tensorfly.cn/tfdoc/get_started/introduction.html https://github.com/CreatCodeBuild/TensorFlow ...

  4. 网络库crash以及boost asio strand dispath分析

    最近在做服务器的稳定性的相关测试,服务器的网络底层使用的是boost asio,然后自己做的二次封装以更好的满足需求. 服务器昨天晚上发现crash了一次,之前测试了将近半个多月,有一次是莫名的退出了 ...

  5. Linux 和 Windows 常用工具列表

    1. Windows 篇 1)MobaItem 一款优秀的Windows下模拟Linux Terminal工具,同时也可以用来远程Linux服务器. 2. Linux 篇 2) MC Linux下非常 ...

  6. pyodbc不支持使用%,应该使用?

    pyodbc不支持使用%,应该使用? 如: Sql插入语句cur.execute("INSERT INTO bb VALUES (?,?,?)","s",&qu ...

  7. C#中ref,out

    out 关键字会导致参数通过引用来传递.这与 ref 关键字类似,不同之处在于 ref 要求变量必须在传递之前进行初始化.若要使用 out 参数,方法定义和调用方法都必须显式使用 out 关键字 比如 ...

  8. HTML5 地理位置定位(HTML5 Geolocation)原理及应用

    地理位置(Geolocation)是 HTML5 的重要特性之一,提供了确定用户位置的功能,借助这个特性能够开发基于位置信息的应用.今天这篇文章向大家介绍一下 HTML5 地理位置定位的基本原理及各个 ...

  9. KMP算法的详细解释及实现

    这是我自己学习算法时有关KMP的学习笔记,代码注释的十分的详细,分享给大家,希望对大家有所帮助 在介绍KMP算法之前, 先来介绍一下朴素模式匹配算法: 朴素模式匹配算法: 假设要从主串S=”goodg ...

  10. ES6笔记一

    遍历数组: 1:传统的 for (var index = 0; index < myArray.length; index++) { console.log(myArray[index]);} ...