第一种方式,zkjbeyond的文章中有很详细的说明http://www.blogjava.net/zkjbeyond/archive/2006/05/05/44676.html
简单说,就是利用Ajax读取包的.js文件后,直接使用eval()运行代码。
除此外,dojo还有另一种加载方式,用在调试阶段(例如使用firebug活Venkman调试dojo时都需要用到,不过我没试过使用MSE7或Visual Studio时是否需要使用这种加载方式)。
你在加载包前,将djConfig.debugAtAllCosts设置为true,那么包的加载方式会有所变化,采用第二种方式。例如:
djConfig.debugAtAllCosts=true;
dojo.require("dojo.widget.TimBar");
dojo.hostenv.writeIncludes();
此时,dojo会使用加载brower_debug.js文件,
brower_debug.js重载了函数dojo.hostenv.loadUri,这儿,不再直接使用eval()运行,而只是把需要的包push到dojo.hostenv.loadedUris数组中。实现代码:
var text = this.getText(uri, null, true);
var requires = dojo.hostenv.getRequiresAndProvides(text);
eval(requires.join(";"));
dojo.hostenv.loadedUris.push(uri); dojo.hostenv.loadedUris[uri] = true;
var delayRequires = dojo.hostenv.getDelayRequiresAndProvides(text);
eval(delayRequires.join(";"));
从代码可以看出,dojo为了保证加载的顺序,使用dojo.hostenv.getRequiresAndProvides函数将提前依赖的包抠出来,用递归提前push到dojo.hostenv.loadedUris中。
而后,在代码最后,我们只要主动使用dojo.hostenv.writeIncludes();函数,就可一次性将被依赖的包利用document.write包含进来。
btw:
当然,这种方法有不少缺陷:
1、使用document.write方式加载包,会有延迟效应,会等待本页面中代码都执行完才执行包中的代码,自己编码时有点绕,影响可读性;
2、从上面代码中看出,dojo会有更多的IO操作,第一dojo已经完整读取了包代码,但是不马上执行,只是用来分析依赖关系;之后,浏览器又要加载一次包代码。
3、包绝对不允许循环引用。当然,从OO角度,不循环引用是好的方式
所以,这种方式只能用在调试期间