理解dojo.require机制
Dojo 提供了一个非常强大的javascript控件库. 在使用dojo之前,用户基本上不需要具备任何基础知识. 你可以用script远程链接到dojo(dojo.js),也可以把dojo.js下载到本地并用script标签加载. 如果你不太了解dojo,可以参考一下如下资料:
大体上,dojo.js和jquery.js 或者 prototype js,里面有很多开发web应用的常用的特性: 包括:
不仅如此,dojo还有很多其他javascript库(jquery,ext等等)所不具有的功能. 其中一个很重要的功能就是模块化的机制 - 模块系统( 模块系统
假设你有一个本地的开发环境,目录结构如下:(
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”dojo/dojo.js”></script> </body> </html> 假设我们要用Flickr API获取数据,这时候,我们就要用到跨域请求,但是这些功能模块并不是在dojo base库里面,我们需要另外加载所需的dojo模块:
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script src=”/dojo/io/script.js”></script> </body> </html> 这里我们可以用script标签解决这种问题,同样还有另外一种方式,这种方式体现了模块系统的宗旨: 我们用
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script> dojo.require(”dojo.io.script”); //Note: do not include the .js </script> </body> </html>
首先, 我们也可以创建自己的模块. 让我们回到Flickr API的例子,我们要开发一个用Flickr数据的大型web应用,我们需要能很好的组织和管理这些javascript代码. 归根结底,我们需要创建名为flickrApp的命名空间用于保存所有该应用的逻辑功能. 为了达到这个目的,我们更新原有的目录结构,创建一个
现在我们可以用
dojo.require() 来加载我们自定义的模块到HTML页面上:
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script> dojo.require(”dojo.io.script”); dojo.require(”flickrApp”); </script> </body> </html> 问题来了, dojo是怎么知道
此时,所有的应用相关的代码都在flickrApp这个目录(名字空间)下,在这个目录下,我们可以更进一步将该应用切分成不同的模块。第一个模块就是 就像我们之前所说的,dojo会从dojo.js(
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script> dojo.require(”dojo.io.script”); dojo.require(”flickrApp. data “); </script> </body> </html> 好了,到此为止,我们来想一想,这样做真的有必要吗,我们为什么不能不要借助这种模块系统,而仅仅是把应用程序所有的逻辑功能都放在一个javascript文件中呢? 当然可以。但是dojo实现模块系统的目的在于更好更方便的管理代码,也便于用工具压缩优化代码。 接下来我们讨论一下最重要的部分:依赖管理. 模块可以包含对其他模块的引用,即在模块中可以require()其他的模块, dojo会帮你管理这些模块,让我们回到我们HTML页面:
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script> dojo.require(”dojo.io.script”); dojo.require(”flickrApp.data”); </script> </body> </html> 我们可以看到,这里我们会在HTML页面上require 这个 此时,我们的HTML页面就只需要包含一个
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script> dojo.require(”flickrApp.data”); </script> </body> </html> dojo会管理这些依赖关系,确保 更有甚者,依赖管理还需要一个响应通知,即当所有依赖的模块都被加载完成后的一个响应通知。这件事情
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/dojo/dojo.js”></script> <script> dojo.require(”flickrApp.data”); dojo.ready(function(){ // Note that dojo.ready() is a shortcut for dojo.addOnLoad() added in Dojo 1.4 // Run code from data.js and all its dependencies safely }); </script> </body> </html>
就像前面提到的,当用到dojo的
其实dojo也提供了我们定义dojo的默认查找路径的方式,我们再更新一下我们应用程序的结构,如下:
可以看到,我们的模块 -
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script src=”/js/dojo1.4.1/dojo.js”></script> <script> dojo.registerModulePath(”some”,“../../some/”); dojo.require(”some.other.module”); </script> </body> </html> 通过
<!DOCTYPE html>
<html lang=”en”> <head> <meta charset=”utf-8″ /> <title>Dojo</title> </head> <body> <script type=”text/javascript”> var djConfig = {modulePaths:{”some”:”../../some/”}}; </script> <script src=”/dojo/dojo1.4.1/dojo.js”></script> <script> dojo.require(”some.other.module”); </script> </body> </html> 其实dojo关于模块系统的内容还有很多,这里我们主要是基于本地的dojo,其实dojo还可以以跨域的方式加载(从AOL或者Google CDN),所以模块系统也会去支持这种特性。模块系统的底层实现是基于XHR去请求模块内容的,这些在你用dojo的CDN版本是会改变,这时模块系统会转换到跨域的方式(基于script元素)。 Dojo之外其实这些模块系统的想法也可以在没有dojo的情况下使用。 YUI3.0也有一个类似的实现,同样,也有一些针对模块系统的想法而专门实现的独立的控件库,其中之一就是RequireJS ,他是基于dojo实现的。有兴趣不妨下载下来研究一下。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |