Dojo学习笔记(二):AMD模块高级使用

简介:






1、配置加载器

 
 

   在整个文章里,我们假设应用的文件结构如下图所示:

/
    index.html
    js/
        lib/
            dojo/
            dijit/
            dojox/
        my/
        util/

   在使用AMD模块之前我们要做的第一件事就是配置加载器,使加载器在异步模式下运行。只要将async属性值改为ture就行:

1
<script data-dojo-config= "async: true"  src= "js/lib/dojo/dojo.js" ></script>

   我们也可以在dojoConfig对象中设置async属性,但使用任意一种方法我们都得保证这个值在loader包含到网页之前设置。如果不这样,加载器就以兼容模式的同步模式运行。

   在异步模式下,加载器只会定义两个全局函数:require用来加载模块;define用来定义模块。新的加载器和旧的加载器最鲜明的对比就是旧加载器会一股脑加载Dojo Base里的所有模块,而新的加载器就不会这样做。

   接下来我们要做的就是给loader配置信息,这些信息里包含我们的模块地址:

1
2
3
4
5
6
7
8
9
10
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代码文件夹的地址,默认值为dojo.js所包含的那个文件夹;tlmSiblingofDojo属性被设置为false代表那些没有指定包、顶层模块的路径默认为baseUrl的地址。如果tlmSiblingofDojo默认值为true,若为true,那么认为他们和dojo包处于同一目录。这时,即使没有明确地定义until包,我们仍然调用until文件夹里的代码。

   包就是模块的集合。packages包含三个主要的配置参数。name表示包的名称,实际值为包含模块的文件夹的名称;location表示包的位置,可以是一个相对于baseUrl路径或绝对路径;main是一个可选参数,表示要加载的模块,默认值为main.js,该属性可以重写,该示例中要加载的模块是app.js,该模块的确切位置是:/js/my/app.js。


2、引用模块

   require函数包含下列参数:

   (1)configuration:可选参数,值为对象,默认值为undefined。用来在加载器运行中修改配置

   (2)dependencies:可选参数,值为数组,默认值为[],要生成模块的依赖项。

   (2)callback:回调函数,你需要你的代码封装在一个回调函数,以支持异步加载和能够使用非全局引用模块。

   示例一:

1
2
3
4
5
6
7
8
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方法接受了一个模块标识符("dependencies")的数组,这个数组将作为它的第一参数,回调函数作为第二参数。数组里的依赖引用是有顺序的。一旦所有的依赖项准备好,它们会被按顺序传入回调函数作为函数的参数。回调函数是可选的,如果你只是想加载他们而并不想做些什么,你就可以忽略回调函数。


   实例二:

1
2
3
4
5
6
7
require({
     baseUrl:  "/js/" ,
     packages: [
         { name:  "dojo" , location:  "//ajax.googleapis.com/ajax/libs/dojo/1.9.2/"  },
         { name:  "my" , location:  "my"  }
     ]
}, [  "my/app"  ]);

   在加载器运行中修改配置,它是通过将配置信息对象作为第一个参数传进去实现的。这样我们改变了配置信息,将dojo包指向了谷歌的CDN,不同于老版本模块机制,AMD机制支持隐式跨域加载,所以没有特殊的跨域版本是必要这样做的。


3、定义模块

   define函数包含下列参数:

   (1)moduleId:可选参数,表示模块签名,默认值为undefined,为了能够兼容旧版AMD语法,推荐不使用.

   (2)dependencies:可选参数,值为数组,默认值为[],要生成模块的依赖项。

   (3)factory:工厂函数,返回模块的值

1
2
3
4
// in "my/_TemplatedWidget.js"
define([  "dojo/_base/declare" "dijit/_WidgetBase" "dijit/_TemplatedMixin"  ],  function (declare, _WidgetBase, _TemplatedMixin){
     return  declare([ _WidgetBase, _TemplatedMixin ], {});
});

   注意,这里我们省略了第一个可选参数:模块签名。也可以这样:return declare("my._TemplatedWidget", [ _WidgetBase, _TemplatedMixin ], {}); 你可能会看到这样的代码,其实这样做事为了能够兼容旧版AMD语法。

   在以上例子中,我们利用dojo.declare创建并返回了一份构造函数,当定义模块时一个重要的事就是工厂函数一旦被调用,加载器就会缓存它返回的值。从实践层面上来看,这就意味着模块可以依据相同的模块来轻松地共享对象。

   采用旧版本Dojo编写的等效代码(不推荐使用):

1
2
3
4
dojo.provide( "my._TemplatedWidget" );
dojo.require( "dijit._WidgetBase" );
dojo.require( "dijit._TemplatedMixin" );
dojo.declare( "my._TemplatedWidget" , [ dijit._WidgetBase, dijit._TemplatedMixin ], {});

   当定义模块时,值也可以作为对象:

1
2
3
4
5
// in "my/nls/common.js"
define({
     greeting:  "Hello!" ,
     howAreYou:  "How are you?"
});

   备注:如果你在定义模块是没有回调函数,你将不可能引用任何的依赖项,所以这种定义方法是罕见的。


4、使用可移植模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dojoConfig = {
     packages: [
         { name:  "dojo16" , location:  "lib/dojo16"  },
         { name:  "dijit16" , location:  "lib/dijit16"  },
         { name:  "dojox16" , location:  "lib/dojox16"  },
         { name:  "dojo" , location:  "lib/dojo"  },
         { name:  "dijit" , location:  "lib/dijit"  },
         { name:  "dojox" , location:  "lib/dojox"  },
         { name:  "myOldApp" , location:  "myOldApp"  },
         { name:  "my" , location:  "my"  }
     ],
     map: {
         myOldApp: {
             dojo:  "dojo16" ,
             dijit:  "dijit16" ,
             dojox:  "dojox16"
         }
     }
};

   如果你的应用需要使用来至两个不同版本的Dojo,新的加载器能够轻松实现。使用map配置实现这种兼容。


5、编写可移植模块

   为了使加载器能够执行可移植包,任何包内的模块引用都得使用relatie标识符。

1
2
3
4
5
6
7
8
// in "my/widget/NavBar.js"
define([
     "dojo/dom" ,
     "my/otherModule" ,
     "my/widget/InfoBox"
],  function (dom, otherModule, InfoBox){
     // …
});

   使用相对模块标识符代替绝对模块标识符:

1
2
3
4
5
6
7
8
// in "my/widget/NavBar.js"
define([
     "dojo/dom" ,
     "../otherModule" ,
     "./InfoBox"
],  function (dom, otherModule, InfoBox){
     // …
});

   相对于"my/widget/NavBar":

   "dojo/dom"在一个独立包中,使用完整标示符

   "my/otherModule"是在上一个目录中, 所以我们使用"../"

   "my/widget/InfoBox"是在同一个目录中,所以我们使用"./"




参考文献:http://dojotoolkit.org/documentation/tutorials/1.9/modules_advanced/

         http://dojotoolkit.org/documentation/tutorials/1.9/dojo_config/




     本文转自stock0991 51CTO博客,原文链接:http://blog.51cto.com/qing0991/1393128,如需转载请自行联系原作者






相关文章
|
20天前
|
开发框架 JavaScript 安全
js开发:请解释什么是Express框架,以及它在项目中的作用。
【4月更文挑战第24天】Express是Node.js的Web开发框架,简化路由管理,支持HTTP请求处理。它包含中间件系统用于日志、错误处理和静态文件服务,集成多种模板引擎如EJS、Jade、Pug。框架还提供安全中间件提升应用安全,并具有良好的可扩展性,便于项目功能扩展和开发效率提升。
26 3
|
5月前
|
前端开发
初学鸿蒙OS之JS-UI框架中基础组件的使用
初学鸿蒙OS之JS-UI框架中基础组件的使用
39 0
|
9月前
|
JavaScript 前端开发
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
深入了解前端开发规范的区别《Commonjs、AMD、CMD、ES6模块化》
73 0
|
9月前
|
SQL JavaScript 关系型数据库
保姆级教程——号称下一代Node.js,Typescript的orm的prisma 如何在nest.js中使用
保姆级教程——号称下一代Node.js,Typescript的orm的prisma 如何在nest.js中使用
|
9月前
|
JavaScript API
说说AMD、CMD、commonJS模块化规范的区别?
说说AMD、CMD、commonJS模块化规范的区别?
107 0
|
9月前
|
JavaScript API
AMD、CMD、commonJS模块化规范的区别
AMD、CMD、commonJS模块化规范的区别
56 0
|
11月前
|
Web App开发 JSON JavaScript
移植nodejs到嵌入式linux,让终端支持可使用js做些功能
移植nodejs到嵌入式linux,让终端支持可使用js做些功能
|
12月前
|
缓存 JavaScript 安全
快速入门nest.js(6/10)--原理细节
依赖注入 我们将依赖的实例委托给IOC容器,在这里,这个IOC容器就是NestJS运行时系统本身,NestJS在这里处理所有繁重的工作,而不是尝试自己实现依赖注入。本质上,当我们“ask”类构造函数中的依赖项时,NestJS处理并检索返回给我们的对象,以及它可能需要的任何依赖项等等。
169 0
|
JavaScript 前端开发
js 模块化基础和模块规范AMD、CMD、ES6模块
js 模块化基础和模块规范AMD、CMD、ES6模块
88 0