轉自:http://blog.csdn.net/dojotoolkit/article/details/5935844javascript
Dojo 提供了一個很是強大的javascript控件庫. 在使用dojo以前,用戶基本上不須要具有任何基礎知識. 你能夠用script遠程連接到dojo(dojo.js), 也能夠把dojo.js下載到本地並用script標籤加載.html
若是你不太瞭解dojo, 能夠參考一下以下資料:java
大致上,dojo.js和jquery.js 或者 prototype js, 裏面有不少開發web應用的經常使用的特性: 包括:jquery
不只如此, dojo還有不少其餘javascript庫(jquery, ext等等)所不具備的功能. 其中一個很重要的功能就是模塊化的機制 - 模塊系統(dojo.require()
). JavaScript 和 瀏覽器自己以及其餘的javascript庫並不支持這種特性, dojo很好的解決了這種問題.web
dojo.require('my.module')
用於加載javascript文件, 功能相似於script標籤的做用.跨域
假設你有一個本地的開發環境,目錄結構以下:(http://localhost:8888
.)瀏覽器
index.html
是一個包含 dojo.js 簡單頁面
.緩存
假設咱們要用Flickr API獲取數據, 這時候,咱們就要用到跨域請求, 可是這些功能模塊並非在dojo base庫裏面, 咱們須要另外加載所需的dojo模塊:安全
這裏咱們能夠用script標籤解決這種問題, 一樣還有另一種方式, 這種方式體現了模塊系統的宗旨: 咱們用dojo.require()
加載 dojo.io.script
app
經過
dojo.require()
咱們得到了一個模塊系統, 它提供了一系列咱們開發複雜web2.0頁面所須要的組件. 接下來的內容咱們會着重介紹模塊系統的特性:
首先, dojo.require()會避免重複加載, 若是script腳本被瀏覽器緩存了, dojo會調用緩存的資源從而避免沒必要要的http請求, 事實上,你能夠隨便調用
dojo.require(), 無論調用了多少
dojo.require(), dojo都會保證一樣的模塊只會被加載一次.
咱們也能夠建立本身的模塊. 讓咱們回到Flickr API的例子, 咱們要開發一個用Flickr數據的大型web應用, 咱們須要能很好的組織和管理這些javascript代碼. 歸根結底,咱們須要建立名爲flickrApp的命名空間用於保存全部該應用的邏輯功能. 爲了達到這個目的, 咱們更新原有的目錄結構, 建立一個flickrApp.js文件:
flickrApp.js看起來彷佛僅僅是一個js文件, 但若是你用dojo的眼光來看他, 你會發現他其實應該是一個模塊, 爲了讓dojo識別他是這個模塊, 咱們用
dojo.provide()
方法初始化這個js文件,將其變爲一個dojo的模塊. 咱們加入以下代碼到 flickrApp.js 文件中:
dojo.provide()
建立了一個以你傳入的字符串(flickrApp
)命名的對象結構(名字空間), 咱們這裏是建立了一個名爲flickrApp的對象, 該對象建立後, 咱們即可以像定義該對象的各個屬性同樣來定義該應用(
flickrApp
)
的各個方面, 下面是 flickrApp.js 一個例子:
dojo.require()
來加載咱們自定義的模塊到HTML頁面上:
問題來了, dojo是怎麼知道flickrApp.js模塊的文件系統中存放的位置的呢? 答案就是dojo的路徑管理機制, dojo會根據你傳入
dojo.provide()
的字符串來定位該模塊的位置,基準點是dojo.js的上一級目錄, 好比dojo.js在
http://localhost:8888/dojo/dojo.js,因此dojo會在
http://localhost:8888/這個目錄級別(dojo.js的上一級)來定位全部的模塊。 爲了說明這個問題, 咱們如今來再一次改變例子的文件結構,使其看起來
更加具備組織性,以下:
此時,全部的應用相關的代碼都在flickrApp這個目錄(名字空間)下,在這個目錄下,咱們能夠更進一步將該應用切分紅不一樣的模塊。第一個模塊就是data.js模塊,包含獲取
Flickr數據的邏輯功能,以及跨域,返回數據等等功能。基於這個改變,咱們須要在data.js裏面加入
dojo.provide()語句來告訴他新的目錄結構的改變,以下(
data.js
):
就像咱們以前所說的,dojo會從dojo.js(http://localhost:8888/dojo/dojo.js
)的上一級目錄來開始定位各個模塊,因此這裏dojo定位咱們的data.js
模塊的路徑爲http://localhost:8888/flickrApp/data.js。此時,咱們的HTML代碼也要作相應的改動:
好了,到此爲止,咱們來想想,這樣作真的有必要嗎,咱們爲何不能不要藉助這種模塊系統,而僅僅是把應用程序全部的邏輯功能都放在一個javascript文件中呢? 固然能夠。可是dojo實現模塊系統的目的在於更好更方便的管理代碼,也便於用工具壓縮優化代碼。
接下來咱們討論一下最重要的部分:依賴管理.
模塊能夠包含對其餘模塊的引用,即在模塊中能夠require()其餘的模塊, dojo會幫你管理這些模塊,讓咱們回到咱們HTML頁面:
咱們能夠看到,這裏咱們會在HTML頁面上require 這個dojo.io.script.js模塊, 事實上咱們能夠把這個
require()語句放到
data.js模塊裏面,其實這裏
data.js模塊是依賴於
dojo.io.script.js模塊的,dojo會管理這個依賴關係,因此此時
data.js模塊以下:
此時,咱們的HTML頁面就只須要包含一個 require()
語句 (data.js模塊)
.
dojo會管理這些依賴關係,確保data.js依賴於
dojo.io.script.js。
更有甚者,依賴管理還須要一個響應通知,即當全部依賴的模塊都被加載完成後的一個響應通知。這件事情能夠用dojo.ready()這個函數來實現,
dojo.ready()將會註冊一個函數,這個函數會在全部的DOM節點加載完成,而且全部模塊及其的依賴模塊都加載和解析完成時 被調用。用法以下:
dojo.ready()
能夠用在任什麼時候間,任何地方,甚至是dojo.ready()的callback方法裏面,好比
:
就像前面提到的,當用到dojo的 require()時,dojo會從dojo.js的上一級目錄開始查找,好比
require('some.other.module')會從
some/other/module.js開始查找:
其實dojo也提供了咱們定義dojo的默認查找路徑的方式,咱們再更新一下咱們應用程序的結構,以下:
能夠看到,咱們的模塊 - some.other.module.js已經在dojo默認的模塊查找路徑以外了,咱們要告訴dojo這個結構的變化就要用到
dojo.registerModulePath():
經過dojo.registerModulePath("some", "../../some/")
語句,dojo便知道這個用戶自定義的模塊的位置,這裏,咱們告訴dojo咱們的自定義模塊some是在dojo.js的上兩級(../../some
),這個時候,dojo便知道了如何去解析這個名字空間(some.other.module
)並加載some.other.module.js文件了。此時此刻,dojo便能識別全部在「
../../some/
」路徑下的自定義模塊。之因此須要這樣作的緣由主要是安全問題,瀏覽器是不支持javascript訪問文件系統的。 若是你對
djConfig 比較瞭解的話,你會發現其實這個對象也能夠用來作「dojo.registerModulePath()
」的工做:
其實dojo關於模塊系統的內容還有不少,這裏咱們主要是基於本地的dojo,其實dojo還能夠以跨域的方式加載(從AOL或者Google CDN),因此模塊系統也會去支持這種特性。模塊系統的底層實現是基於XHR去請求模塊內容的,這些在你用dojo的CDN版本是會改變,這時模塊系統會轉換到跨域的方式(基於script元素)。
其實這些模塊系統的想法也能夠在沒有dojo的狀況下使用。 YUI3.0也有一個相似的實現,一樣,也有一些針對模塊系統的想法而專門實現的獨立的控件庫,其中之一就是RequireJS ,他是基於dojo實現的。有興趣不妨下載下來研究一下。