1、前言
?? dojo利用ajax技術,基本實現的按需要下載js文件,估計與國內jsvm有類似功能(jsvm好久沒關注了,不好亂說)。
?? a、類庫開發人員可以在dojo基礎上開發自己的javascript類庫。(dojo提供的夠多的了,并不斷擴大)?
?? b、可以按照每個頁面的需要,加載有限的類庫。
?? c、提供了很好的package機制。與java不同,采用dojo的包機制有一定寫法要求。見后面說明。
?? d、急劇縮小了類庫大小。以前寫過篇 (亂評prototype.js)中提到過。其實dojo不象我們想的那么龐大,只需要bootstrap1.js? hostenv_browser.js? bootstrap2.js實現底層代碼,其它功能代碼按需下載。很擔憂propotype.js的不斷龐大啊。
2、包加載機制源碼解讀
?? 其實包加載機制只用到bootstrap1.js? hostenv_browser.js? bootstrap2.js這三個文件。 大家可以看我 例子中 lang.htm ,動態的取lang.js,然后調用函數。使用上也比較簡單。 例子中我加了些注釋,歡迎大家拍磚。以下我說下個文件作用,以及dojo.require("");函數調用流程。
?? bootstrap1.js 啟動dojo的第一段代碼,定義了些全局變量和全局函數。主要定義了dojo.hostenv”接口“,分別由hostenv_*.js來實現。dojo并不只用在網頁環境中。
?? hostenv_browser.js,瀏覽器環境下實現dojo.hostenv的某些方法。根據navigator對象判斷當前瀏覽器的版本,類型,支持的插件....(見dojo.render對象)。還給window.onload()方法注冊了dojo的幾個方法。
?? bootstrap2.js? 定義了幾個面向類庫使用者的幾個方法。主要有? dojo.require? dojo.provide 等。這些方法其實調用bootstrap1.js中的方法。
?? 當我們調用
?? dojo.require("dojo.lang");時,有以下幾個流程。
?? a、dojo.hostenv.loadModule方法,在bootstrap1.js中,根據傳入的參數如dojo.lang,轉化成文件名? src/lang.js文件。(當然對于失敗流程,如cache檢查,異常處理等,這不具體細訴了)
?? b、dojo.hostenv.loadPath方法,得到javascript文件的url,用xmlhttp得到js文件的內容,eval(s)執行,相當于引入了該文件。
?? c、寫入cache,加標識等后續方法。告訴dojo,我們加載過這個模塊了。
?? d、關于dojo的根文件路徑比較麻煩,請讀 hostenv_browser.js 中設置djConfig["baseScriptUri"] 部分。xmlhttp中js的url是? getBaseScriptUri()+getModulePrefix+lang.js(''+'src'+'/lang.js')? 組成。
?? 具體dojo流程還是比較復雜的,還支持dojo.lang.*等,復雜的處理。
3、如何讓dojo加載自己的類庫
?? 我在附件中包括一個簡單的例子(有中文問題)。有以下幾個注意的地方。
?? a、一定要引入bootstrap1.js? hostenv_browser.js? bootstrap2.js三個文件。dojo下載壓縮包里的dojo.js包括了這三個文件,但也包括可許多你可能用不到的類庫(lang io等)
?? b、設置你的類庫”包名“。如dojo.setModulePrefix('com.founder','javascript');說明com.founder包下文件都在javascript文件夾下建立。 你的類庫必須放到javascript文件夾下面。
?? c、你的類庫文件。如javascript/myjs.js文件,必須首先聲名 dojo.provide("com.founder.myjs");你的類庫必須以com.founder.myjs開頭。
?? d、你的函數或變量必須定義為com.founder.myjs.fun。
?? e、當你調用的時候,只需dojo.require("com.founder.myjs");。這樣,myjs.js文件會下載到本地。可以直接應用了。
關于自己完成自己的類庫,建議先多讀讀dojo的其他代碼吧。這樣才能更好的應用dojo包機制。應用了dojo,可能javascript的寫法上與平時絕對不一樣,但請注意,dojo千萬別亂用,就google dojo中文文檔很少,估計國內系統也沒什么用的吧。
4、亂評dojo
a、javascript類庫的文檔實在不好弄,就dojo官方網站上轉半天也找不到個系統的介紹,中文文檔也很少。maillist到是挺活躍的。不看源代碼能用好dojo我估計懸。
b、dojo野心極大,需要做的工作還很多。無形中加大dojo的應用難度。就象java中的spring,還好有EJB這個墊腳石。可dojo,推廣難度不小啊。
c、下載包中壓縮版dojo.js包括了../src/bootstrap1.js,../src/hostenv_browser.js,../src/bootstrap2.js,../src/lang.js,../src/string.js,../src/io.js,../src/dom.js,../src/io/BrowserIO.js,../src/event.js,../src/event/topic.js,../src/event/browser.js,../src/event/__package__.js,../src/alg/Alg.js,../src/alg/__package__.js,../src/uri/Uri.js,../src/math.js,../src/graphics/color.js,../src/style.js,../src/html.js,../src/math/curves.js,../src/animation/Animation.js,../src/animation/__package__.js,../src/fx/html.js,../src/fx/__package__.js,../src/graphics/htmlEffects.js,../src/graphics/__package__.js
這么多個文件,140k。其實也不大,但包括了很多模塊。估計dojo的定位就是開發"One page One Application"吧。一般的web應用程序prototype.js就夠了。
d、dojo上手相對較難,不象prototype.js。(雖然它們不是一類型的項目,但我喜歡拿一塊比較,原因之一是它們沒有服務器端的功能)。我相信dojo提供的功能能夠覆蓋prototype.js,或者我們可以自己把prototype.js移植到dojo.
e、
5、例子說明
?? 附件中例子我在源代碼中加了注釋和debug,只供大家參考。
附件
--------------
豈不是要支持xmlhttp的瀏覽器才能用?
好像都是加載類庫啊?有什么區別嗎?
require是使用包。
provide是定義包使用。
中文問題就是這樣搞定的。
js文件保存為UTF8編碼就可以了。
如可以搞個 batchrequire嗎?
還有_packageName_.js不爽
>>如可以搞個 batchrequire嗎?
>>還有_packageName_.js不爽
可以講一講:_packageName_.js到底是如何動作的嗎。搞了幾天了,也不明白。
如果只是想做腳本管理,建議使用JSPackager,一個通用的腳本管理框架,甚至可以在不修改原有腳本的條件下給已有腳本庫加上包的概念,并管理他們的依賴。
!!...
QQ:63980499
PFPF
在網上發現你的文章,很好!
照著你的說明,我自已書寫了函數,意在實現動態加載js.
1.首先在服務器端定義一個Hello類如下示:
/**
* myTest.js 對外提供類Hello
**/
function Hello(){
var message = null;
Hello.prototype.setMsg = function(msg)
{
message = msg;
}
Hello.prototype.sayHi = function()
{
if(message == null)
{
message = 'hello ';
}
alert(message);
}
};
2.通過ajax向服務器端請求此文檔.
如下示:
var parameter = "./ajax/myTest.js";
ajax.requestTextAsyn(parameter,"getData");
這里的ajax對象是我之前寫的一個ajax封裝類,能夠成功的向服務器端索取任一資源,調用的方法requestTextAsyn,第一參數是請求的路徑.第二個參數,是一個回調函數名(如果返回成功,此函數將被調用,并具傳入返回的Text)
3.當請求成功后,其將回調getData方法,getData方法定義如下:
function getData(value)
{
/*解析載入的js文檔,當然,如果路徑不正確,或者代碼錯,則應拋出異常,這里略去*/
eval(value);
/*執行此語句*/
hello = new Hello();
hello.setMsg("您好!");
hello.sayHi();
//此句之前一切正常,正功顯示"您好!",然后,我調用了test()方法
test();//test function will fail
}
4.test函數定義如下:
function test()
{
var hello = new Hello();
hello.sayHi();
}
程序將在var hello = new Hello();處運行失敗!
原因很簡單,Hello類對test()是不可見的.它并不知有此定義.
所以扔出異常,Hello標識不存在!
為解決這個問題,我可以將在getData(value)中獲取到的js文檔內容保存下來,在test()函數中再利用eval,申明一次,我測試了,此方法可行.但問題是,效率并不高.
現在的問題就是,如果我將這個js載入了,我如何操作,才能使返回的js文檔僅被解析一次!
我認真的看了,你對dojo的分析,及你寫的例子,沒有發現dojo去解決類似的問題,我知道,我說的并不很清楚,如果你愿意可以通過anlaneg@qq.com與我討論,
我很企待你能說明,dojo如何來保證這點!
我有個問題想問問
我用DOJO作頁面,
用http://localhost:8080/myproject是正常的" target="_new" rel="nofollow">http://localhost:8080/myproject是正常的
但我用ispconfig的路徑映射
http://localhost:8080/myproject ->http://localhost/myproject的時候
其他的還正常,但有些我自己的寫的widget的js文件卻找不到
其他的JS可以找到
是不是DOJO的打包機制的問題?