dojoConfig 对象(1.6是djConfig) 允许你设置toolkit的不同选项及默认的行为。 本教程中我们擦讨可以在dojoConfig中配置什么及如何使用。 介绍 dojoConfig 对象(Dojo 1.6为 djConfig) 用于配置一个网
dojoConfig 对象(1.6是djConfig) 允许你设置toolkit的不同选项及默认的行为。 本教程中我们擦讨可以在dojoConfig中配置什么及如何使用。
介绍
dojoConfig 对象(Dojo 1.6为 djConfig) 用于配置一个网页或者应用程序中的Dojo, 该对象在运行时会被模块加载器(loader)引用以及Dojo的组件使用全局选项。如若需要, 在更深层次的使用中, 可以做为自定义应用程序的一个配置点。!* 老的对象名djConfig已被弃用, 但在2.0之前已经存在的代码依然有效。 在写本教程时,许多文档依然使用djConfig; 两种写法是相等的,只是强烈建议你使用 dojoConfig.
开始
让我们通过一些简单的例子来看看dojoConfig是如何工作的。 首先, 是一个直接设置dojoConfig对象的例子:<!-- set Dojo configuration, load Dojo --> <script> dojoConfig= { has: { "dojo-firebug": true }, parseOnLoad: false, foo: "bar", async: true }; </script> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"></script> <script> // Require the registry, parser, Dialog, and wait for domReady require(["dijit/registry", "dojo/parser", "dojo/json", "dojo/_base/config", "dijit/Dialog", "dojo/domReady!"] , function(registry, parser, JSON, config) { // Explicitly parse the page parser.parse(); // Find the dialog var dialog = registry.byId("dialog"); // Set the content equal to what dojo.config is dialog.set("content", "<pre>" + JSON.stringify(config, null, "\t") + "</pre>"); // Show the dialog dialog.show(); }); </script> <!-- and later in the page --> <div id="dialog" data-dojo-type="dijit.Dialog" data-dojo-props="title: 'dojoConfig / dojo/_base/config'"></div>
!* 注意dojoConfig 必须在 dojo.js之前被定义。 这非常重要,如果反过来的话,配置的属性会被忽略。
在以上这个例子中, 我们设置了三个标志: parseOnLoad: false, has(dojo-firebug 子属性)和 async:true. 另外, 还自定义了 foo: "bar". 在这个例子中, 一个dijit.Dialog(弹出窗口)位于网页中。 代码从require的回调函数开始运行, 将dojo.config的值转化为 JSON, 并且作为对话框的内容展示。 在展示出来的结果中,有parseOnLoad, has, foo属性。 但也有一些其它的属性, 如packages, baseUrl.
!* 需要注间dojoConfig 和dojo/_base/config之前的区别, dojoConfig 纯粹是以输入为目的——如何传递配置参数给loader和模块。 在loader启动处理时, dojo/_base/config 会被这些配置填充,之后为模块查找配置使用。
以下是一个在声明语句中的配置,等同于上面的例子:
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js" data-dojo-config="has:{'dojo-firebug': true}, parseOnLoad: false, foo: 'bar', async: 1"> </script>
在这里,我们在Dojo的 script 元素中使用了data-dojo-config 属性, 你可能在其它的教程或者例子中看到过。 它跟之前的例子有完全一样的功能。 在这两种情况下, 我们提供的配置选项最后都会被混入到dojo/_base/config对象中, 在 dojo.js加载启动后,可以在dojo/_base/config 找到我们提供的配置选项。
你可以通过在dojoConfig添加新的值来确认,在console 检查dojo.config对象。 所以dojoConfig就是Dojo装配置属性的一个袋子。 让我们看看在这里有哪些选项及如何使用它们。
has() 配置
has() 是 Dojo 1.7中添加的一个重要功能,用于特征检测。 我们可以在dojoConfig中为has()指定特征, has()的值是一个包含所有特征检测的散列对象。这个特征集用于确定在Dojo支持哪些功能。 例如, 我们可以禁用amd factory scan(扫描CommonJS 请求(模块)语句,并作为依赖加载)<script> dojoConfig = { has: { "dojo-amd-factory-scan": false } }; </script>
Debug/Firebug 配置
通过其它的教程或使用过Dojo 1.7之前的版本,你现在可能对isDebug 配置标志已经很熟悉。isDebug用来启动调试信息。 在Dojo 1.7+, 你也可以在更高层次的颗粒上(更细的控制),通过指定一个has() 特征来完成。为了在老的IE中启用Firebug Lite调试功能, 我们可以设置dojo-firebug特征检测(依然可以设置isDebug, 但使用特片将会在异步模式加载周期中更早的加载)。 如果你已经有Firebug或者其它的 console. 它不会做任何事忙你的吧。 但如果你没有一个控制台(console), 它会加载Dojo版本的Firebug Lite (之前看奔驰中有用Javascript写过一个控制定,是一个弹出窗口,窗口会输出调试的结果), 并且创建页面的底部创建一个Console UI. 它便于在IE的老版本或者没有很好开发者工具的浏览器中调试。为了查看到你使用了弃用的和实验性(还没有稳定)的API时的警告消息,你需要设置dojo-debug-messages 特征为true (默认为false, 除非你设置了isDebug)。 如果为 false, 不会出现这些警告。 以下是启用 开发者控制台(浏览器本身有控制台,没有启用 Firebug Lite) 和 记录调试消息:
<script> dojoConfig = { has: { "dojo-firebug": true, "dojo-debug-messages": true } }; </script>
为了禁用有保证的console对象(因为在 IE中没有console对象,在使用原生的console会出错,所以Dojo会创建一个console对象,保证在任何浏览器下都不会报错), 我们可以设置 dojo-guarantee-console 特片为false. 默认为 true, 会创建一个虚拟的console对象。 console的其它特征配配置如下:
- deBugContainerId: 指定一个元素来包含 console UI
- popup: 弹出一个窗口,而不是在当前窗口中渲染console UI.
Loader 配置
Dojo 在 1.7版本中采用了新的加载器(loader)来适应AMD的模块格式。 新的加载器添加了定义packages, maps等多种新的配置选项。查看更多的关于loader的细节,可以查看 Advanced AMDusage tutorial . 更要的加载器配置参数如下:- baseUrl: 当模块标识符被转化为路径或者URL时, 根路径会被添加到最前面。
baseUrl: "/js"
- packages: 包含多个包对象的数组, 每个包对象由包名和位置组成
packages: [{ name: "myapp", location: "/js/myapp" }]
- map: 允许你将模块标识符的路径映射到其它不同的路径上:
map: { dijit16: { dojo: "dojo16" } }
- paths: 映射模块id(标识符)的部分到一个文件路径上:
var dojoConfig = { packages: [ "package1", "package2" ], paths: { package1: "../lib/package1", package2: "/js/package2" } }; // ...is equivalent to: var dojoConfig = { packages: [ { name: "package1", location: "../lib/package1" }, { name: "package2", location: "/js/package2" } ] };
- async: 如果Dojo的核心需要被异步加载,应当定义它。 它的值可以是true, false 或者 leagacyAsync. legacyAsync 会让loader永久的使用跨域的模式。
async: true
- parseOnLoad: 如果为true时,当有了网页节点结构(DOM)并且所有的初始化的依赖( 包括 dojoConfig.deps数组中指定的依赖)被加载完成时,dojo/parser会解析网页。
parseOnLoad: true
!* 推荐你将parseOnLoad设置为false(默认为false, 所以你可以不需要设置此属性),之后开发者可以在require中明确的请求dojo/parser模块,并调用parser.parse(); - deps: 指定资源路径(模块或者其它文本,图片)的数组,数组里的模块会在Dojo被加载完时,立即被加载。
deps: ["dojo/parser"]
- callback: 一旦deps中的模块被加载,该回调函数会被执行
callback: function(parser) { // Use the resources provided here }
- waitSeconds: 等待加载一个模块的时间,默认为0 (一直等待)
waitSeconds: 5
- cacheBust: 如果为true, 给每一个模块URL末尾添加一个时间,避免模块被缓存
cacheBust: true
<!-- Configure Dojo first --> <script> dojoConfig = { has: { "dojo-firebug": true, "dojo-debug-messages": true }, // Don't attempt to parse the page for widgets parseOnLoad: false, packages: [ // Any references to a "demo" resource should load modules locally, *not* from CDN { name: "demo", location: "/documentation/tutorials/1.9/dojo_config/demo" } ], // Timeout after 10 seconds waitSeconds: 10, map: { // Instead of having to type "dojo/domReady!", we just want "ready!" instead "*": { ready: "dojo/domReady" } }, // Get "fresh" resources cacheBust: true }; </script> <!-- Load Dojo, Dijit, and DojoX resources from Google CDN --> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"></script> <!-- Load a "demo" module --> <script> require(["demo/AuthoredDialog", "dojo/parser", "ready!"], function(AuthoredDialog, parser) { // Parse the page parser.parse(); // Do something with demo/AuthoredDialog... }); </script>
当使用了packages配置时, 我们已所有引用demo/* 的模块都指向了本地/documentation/tutorials/1.9/dojo_config/demo/ 文件夹, 同时允许dojo, digit和dojox从Google CDN中引用。 一旦没有指定demo package, 请求demo/AuthoredDialog会加载 //ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/demo/AuthoredDialog.js. 我们也可以使用别名(alias), 将 ready 与 dojo/domReady连结起来。
loader文档提供了更多详细信息。
本地与国际化
Dojo 的 i18n 系统有它自己的文档 和教程, 我们仅在这里展示关于它在dojoConfig的配置。你可以通过dojoConfig, 给任何窗口部件配置它的本地化或者使用Dojo 国际化来本地化内容。 locale选项可以覆盖你浏览器给Dojo提供的默认置(Dojo会获得浏览器的Locale). 一个简单的例子如下:
<script> var dojoConfig = { has: { "dojo-firebug": true, "dojo-debug-messages": true }, parseOnLoad: true, // look for a locale=xx query string param, else default to 'en-us' locale: location.search.match(/locale=([\w\-]+)/) ? RegExp.$1 : "en-us" }; </script> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"></script> <script> require(["dojo/date/locale", "dijit/Dialog", "dojo/json", "dojo/_base/config", "dojo/_base/window", "dojo/i18n", "dojo/domReady!"] , function(locale, Dialog, JSON, config, win) { var now = new Date(); var dialog = new Dialog({ id: "dialog", // set a title on the dialog of today's date, // using a localized date format title: "Today: " + locale.format(now, { formatLength:"full", selector:"date" }) }).placeAt(win.body()); dialog.startup(); dialog.set("content", "<pre>" + JSON.stringify(config, null, "\t") + "</pre>"); dialog.show(); }); </script>
查看示例
在这个demo中, 我们在dojoConfig对象里定义了locale属性, 我们会在查询语句中寻找 locale=xx的参数。 这里只是给你演示一相,一般你会直接指定一个locale. 将locale模块设置在所有要加载模块之前,是为了确保其它模块中依赖的本地化资源包正确的加载。 这样,我们就可以用dojo/date/locale模块来格式化一个date对象, 生成的本地化字符串为作为 窗口的标题。
!* 在多语言的网页中, 你将需要加载其它locale资源包以及浏览器指定的或者dojoConfig.locale属性(多种locale), 这种情况下, 需要使用extraLocale配置属性, 它是由 locale名称字符串组成的一个数组。
自定义属性
由于dojo.config 一直存在, 它可以给Dojo中的其它模块提供自己的配置属性。 我们可以在Digit看到,特别是DojoX, 这些模块的标志和行为可以有如下设置:Digit Editor allowXdRichTextSave
dojox GFX dojoxGfxSvgProxyFrameUrl, forceGfxRenderer, gfxRenderer
dojox.html metrics fontSizeWatch
dojox.io transports and plugins xipclienUrl, dojoCallbackUrl
dojox.image preloadImages
dojox.analytics plugins sendInterval, inTransitRetry, analyticsUrl, sendMethod, maxRequestSize, idleTime, watchMouseOver, sampleDelay, targetProps, windowConnects, urchin
dojox.cometd cometdRoot
dojox.form.FileUploader uploaderPath
dojox.mobile mblApplyPageStyles, mblHideAddressBar, mblAlwaysHideAddressBar, mobileAnim, mblLoadCompatCssFiles
自定义的属性可以在dojox 模块中工作的很好,那么在你自己的应用程序或者模块中也是一样的。 dojoConfig 最适合于给整个网页或应用程序提供配置。 思考下下面的代码:
<script> dojoConfig = { has: { "dojo-firebug": true }, app: { userName: "Anonymous" } }; </script> <script src="//ajax.googleapis.com/ajax/libs/dojo/1.9.2/dojo/dojo.js"></script> <script> require(["dijit/Dialog", "dijit/registry", "dojo/parser", "dojo/_base/lang", "dojo/json", "dojo/_base/config", "dojo/io-query", "dojo/domReady!"] , function(Dialog, registry, parser, lang, JSON, config, ioQuery) { // pull configuration from the query string // and mix it into our app config var queryParams = ioQuery.queryToObject(location.search.substring(1)); lang.mixin(config.app, queryParams); // Create a dialog var dialog = new Dialog({ title: "Welcome back " + config.app.userName, content: "<pre>" + JSON.stringify(config, null, "\t") + "</pre>" }); // Draw on the app config to put up a personalized message dialog.show(); }); </script>
查看示例
在这个例子中,我们附加了一个"app"属性, 之后我们通过dojo.config来引用它,为对话窗口提供一个个性化的问候。在dojoConfig.app可以填充更多的内容, 它可以预先提供一个合理的默认值,之后在混入具体的值。 在生产中, dojoConfig 代码块被服务器端重写。 另外, 你可以用使用JSON格式的cookie来填充, 或者像之前的例子中,你可以从查询字符串抽取出配置信息。 在开发和测试时, 你可以使用有虚拟值的模板, 或者加载一个js文件或者模块来填充。
附录
- dojoconfig(djConfig) documentation
- Dojo AMD loader configuration reference
- i18n docs