Dojo 1.6 新特性: 异步模块加载机制AMD

本文翻译自: Asynchronous Modules Come to Dojo 1.6

原作者: Kris Zyp

翻译: feijia

在最新的 1.6 版本中, Dojo(Core) Dijit 已经进行了代码重构首次引入了符合 CommonsJS AMD API 规范的异步模块加载机制 (AMD)

模块的兼容性

通过重构,现在 Dojo 的模块已经完全和下列框架兼容 :

灵活性 , 性能提升 堆栈状态

这次重构给 Dojo 带来了极好的灵活性,既可以支持传统的同步装载,也可以支持新的基于标签的装载机制。使用新的装载机制会带来很大的性能提升,并且降低了调试的难度 ( 因为你可以看到很清晰的堆栈状态 )

匿名模块

AMD 模块规范的另一个重要的优势是它允许定义匿名模块, 降低了代码与其所属模块的名称间的耦合。使用匿名模块,模块的名称与身份符合 DRY 原则, Don’t repeat yourself , 避免了模块名字在源代码文件名和代码本身中的重复。这种做法使得代码的更容易移植,一段代码可以被放置在任意文件夹或包中而不用修改代码本身。(译者:一个匿名模块在使用时可以随意定义其名字 , 因此可以很容易的解决模块的重名等冲突情形)。 AMD 使用斜杠分割的模块名而不是使用点分割模块名,从而模块路径可以更直接的映射到 URL ,并允许使用相对路径来引用其他模块。这使得树状文件夹结构也有了移植性 . ( 一个包含一组模块的文件夹可以被移动,改名,而其所包含的模块文件的相对名称不会失效 )

向后兼容性

所有基于传统的 dojo.provide/dojo.require 的代码将仍然有效。 默认情况下, Dojo 使用一个向后兼容的同步加载器,所以你可以继续使用下面的代码 :


使用新的模块加载机制

虽然传统的同步机制和 api 仍然保留,不过你已经可以在 Dojo1.6 中尝试使用新的 AMD 模块加载器来享受 异步加载的好处了 (速度更快,性能更好)

警告 : Dojo 1.6 中, 针对 AMD 的重构仍然属于一个过渡期的改动 , 用户自己开发的 AMD 模块还不能被 Dojo 的加载器和 Build 系统支持 . 1.6 中现有的 编译 系统对 AMD 的支持还非常局限。 如果你自己开发了 AMD 格式的模块,并且你仍然在使用默认的 Dojo 同步模块加载器,那么你必须严格遵循 Dojo 模块的格式 ( 包括换行的格式 ) 来保证你自己的模块能够成功编译 .

Dojo 1.6 中并未官方支持对于 AMD 模块的编译, 但是如果你可以遵循 Dojo 模块的声明风格,编译系统当然也会正常工作。 而由 RequireJS Backdraft 提供的编译工具是为 AMD 专门设计的,因此具有更好的鲁棒性。

虽然 Dojo 1.6 并没有正式声明支持用户自定义的 AMD 模块或异步加载,但是许多用户已经成功的测试过了,并且这无疑是 Dojo 未来将会正式支持的特性 .

创建一个 AMD 模块非常简单:

define 方法的第一个参数中 传入一个数组 定义该模块依赖的其他模块

提供一个回调函数,当依赖模块都加载完毕后可以执行你的模块


这样定义的模块就已经可以被 Dojo 异步加载器或 RequireJS 所使用了。同时你也可以用标准的 dojo.require() 来使用。

总结一下在 Dojo1.6 中你可以使用的几种加载方式 :

  • 用传统的方法 (dojo.require()/dojo.provide()) – 这些模块,只能被 Dojo 同步加载器 加载,但可以被 Dojo 编译系统(Build System )正确的编译
  • Dojo 同步加载器来加载 AMD 格式 define ()) 模块 这些模块可以被正常的加载,并且可以被其他兼容 AMD 格式的加载器加载 . 现在虽然 Dojo1.6 还没有正式支持这种用法, 但在目前的 Dojo1.6 编译系统中,是可以正常工作的 . ( 前提是你必须严格遵循 Dojo 模块定义的代码规范 )
  • 使用第三方加载器来加载 AMD 格式( define ())模块 模块可以被正常加载,并且可以被其他加载器所使用 . 这些模块可以使用 RequireJS Backdraft 提供的编译系统正常编译,但是 Dojo 还没有正式的测试过和其他加载器的兼容性 .

模块的引用

当在 Dojo 中使用 AMD 格式时,有下列几种方式来引用一个模块 .

首先, AMD 推荐的模块引用方法是将需要引用的模块声明在依赖模块声明中,并且在回调函数定义时使用相应的参数作为该模块的假名 , 像我们在前面声明一个使用 dijit.tree 的模块那样 . 然而,这种做法并不被 Dojo 1.6 编译系统所支持 . 这种格式只能适用于 AMD 完全兼容的加载器中。例如:


这样做相对于使用嵌套对象作为命名空间的来引用模块中的对象的传统方法来说有很大优势。因为我们不再需要重复的去键入一个完整的命名空间路径了 . (译者 : 过去要引用 dijit.Tree 的中的某个方法,我们需要每次都使用 dijit.tree )而现在我们只需要在依赖定义中给出一次完整的路径 dojo/cookie dijit/tree , 一旦它们被加载,回调函数中我们就可以直接使用该模块的假名来引用它了 ( 本例中就是 cookie, Tree) .

然而, 对于那些需要继续使用 Dojo 现有的编译系统,或是希望保留现有的代码风格,或是希望把现有的代码移植到新的 AMD 格式的人来说, 我们可以将 dojo,dijit 声明为依赖模块,这样原有的代码就可以正常工作了。 需要注意的是, 即便如此,我们仍然需要列出我们的依赖模块(dojo/cookiet 和dijit/tree),虽然在代码里我们不会直接使用它们了 , 例如上面的代码可以改写成


显然这样的代码有点啰嗦, 但是它使得传统的 Dojo 代码风格得以保持,因此在移植现有代码时尤为有用

另外需要注意的是, 新的 AMD 格式的代码模块不能和旧版的 Dojo 一起工作。 因此你不能直接复制一个 Dojo 1.6 的模块到某个过去版本的 Dojo 里。 如果你想这样做, 你需要手动的去修改这些模块,把它们改成使用 dojo.require/dojo.provide API (当然,类似的你要去修改所有被该模块引用的模块)

联合使用 Dojo RequireJS

Dojo 可以在 RequireJS 上运行,使用 RequireJS 作为其模块加载器。 首先,加载 RequireJS 然后把 Dojo 配置成一个包 :


接下来,我们就可以装载自己的应用程序模块了, 该模块使用 Dojo 作为其依赖


My-module 定义如下 :


在与 Dojo 一起使用 RequireJS 时需要注意以下几点 :

  • RequireJS 在管理模块的加载,因此 Dojo 不知道何时去解析 HTML 中的通过声明方式定义的控件。在页面加载完成,并且你所需要的所有模块都加载完成后,你需要手动的调用 dojo.parser.parse()
  • 需要使用 RequireJS 提供的编译工具

我们会在近期提供如何集成 Backdraft Dojo 的信息,这项工作很快会开始 .

我们还在开发一个包安装工具,它可以自动生成你的配置信息。

我们非常期待看到通过将 AMD 引入 Dojo 带来的改进。 这也是我们走向包自动管理( autonomous packages )的一个关键步骤。请在近期持续关注我们发布的信息。 如果你也对此感兴趣,请告诉我们

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易知道用户保存了什么,我希望当用户第一次看到网格时,网格处于不可编辑状态.当用户准备好后,他们可以单击编辑按钮,这将使网格的某些部分可编辑.然后,有一个保存或取消按钮可以保存更改或还原.在大多数情况下它是有效的.但
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以轻松打包为Web,Mobiles和可能的Standalone版本的方式来实现这一目标.我不想使用Flash.因此,我确信(无论如何我会听取建议)使用JavaScript和SVG.我正在对这个问题进行大量研究,但我很难把各个部分放在一起.我知道Raphae
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部件–我在表单中使用–将固定格式(JavaScript基本格式)的实数值(例如:12.56)设置为HTML表单输入字段(但根据浏览器区域设置显示/编辑它们,所以用户总是看到格式正确的数字).另一方面,Grails期望输入字段根据浏览器
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforjavaScript的学习历程,本篇将从最开始的arcgisapiforjavaScript部署开始,个人声明:博文不在传道受业解惑,旨在方便日后复习查阅。由于是自学,文章中可能会出现一些纰漏,请留言指出,不必留有情面哦!2.下载ArcGISforDe
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑:Thedeclarefunctionisdefinedinthedojo/_base/declaremodule.declareacceptsthreearguments:className,superClass,andproperties.ClassNameTheclassNameargumentrepresentsthenameofthec
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这个问题曾多次被问到,但为了弄清楚我的事实,我需要澄清一些事情,因为我在客户端技术方面的经验非常有限.我们决定使用GWT而不是纯JavaScript框架构建我们的解决方案(假设有更多的Java经验).这些是支持我的决定的事实.>
路由dojo/framework/srcouting/README.mdcommitb682b06ace25eea86d190e56dd81042565b35ed1Dojo应用程序的路由路由FeaturesRoute配置路径参数RouterHistoryManagersHashHistoryStateHistoryMemoryHistoryOutletEventRouterContextInjectionOutl
请原谅我的无知,因为我对jquery并不熟悉.是否有dojo.connect()的等价物?我找到了这个解决方案:http:/hink-robot.com/2009/06/hitch-object-oriented-event-handlers-with-jquery/但是没有断开功能!你知道jquery的其他解决方案吗?有jquery.connect但这个插件在我的测试中不起作用.
与java类一样,在dojo里也可以定义constructor 构造函数,在创建一个实例时可以对需要的属性进行初始化。//定义一个类mqsy_yjvar mqsy_yj=declare(null,{     //thedefaultusername    username: "yanjun",          //theconstructor   
我一直在寻找一些最佳实践,并想知道Dojo是否具有框架特定的最佳实践,还是最好只使用通用的Javascript标准?特别是我主要是寻找一些功能和类评论的指导方针?解决方法:对于初学者来说,这是项目的风格指南:DojoStyleGuide
我有’05/17/2010’的价值我想通过使用dojo.date.locale将其作为“2010年5月17日”.我尝试过使用dojo.date.locale.parse,如下所示:x='05/17/2010'varx=dojo.date.locale.parse(x,{datePattern:"MM/dd/yyyy",selector:"date"});alert(x)这并没有给我所需的日期
我正在尝试创建一个包含函数的dojo类,这些函数又调用此类中的其他函数,如下所示:dojo.provide("my.drawing");dojo.declare("my.drawing",null,{constructor:function(/*Object*/args){dojo.safeMixin(this,args);this.container=args[0];
我知道你可以使用jQuery.noConflict为jQuery做这件事.有没有办法与Dojo做类似的事情?解决方法:我相信你可以.有关在页面上运行多个版本的Dojo,请参阅thispage.它很繁琐,但似乎是你正在寻找的东西.一般来说,Dojo和jQuery都非常小心,不会破坏彼此或其他任何人的变量名.
我有一个EnhancedGrid,用户经常使用复杂的过滤器.有没有办法允许用户保存或标记过滤器,以便将来可以轻松地重新应用它?我知道我可以通过编程方式设置过滤器,但我无法预测用户想要的过滤器.谢谢!编辑:自己做了一些进展…使用grid.getFilter()返回过滤器的JSON表示,然后使用json.strin
我有这个代码:dojo.declare("City",null,{constructor:function(cityid,cityinfo){}});dojo.declare("TPolyline",GPolyline,{constructor:function(points,color){},initialize:function(map){});应该是什
我遇到的问题是我的所有javascript错误似乎来自dojo.xd.js或子模块.我正在使用chrome调试器和许多dijit功能,如dijit.declaration和dojo.parser.这有点烦人,因为它很难找到简单的错误或滑倒.我希望我可以添加一个选项,允许我的调试器在我的非dojo代码中显示选项会发生的位置.我是
我正在使用DojoToolkit数字/解析函数来处理格式化和使用ICU模式语法解析字符串.有没有人知道有可能采取任意ICU模式字符串并以某种方式使用Dojo(或其他)库将其分解为它的部分(例如,对于数字模式,它可以被分解为小数位数,数千个分组等…).我希望这样做,而不需要让我的代码密切了
我有两个看似相关的问题,访问在不同的地方定义的javascript函数.我遇到的第一个问题是调用我在firgbug或safari控制台中定义的函数.我定义了一个名为getRed的函数,如下所示:functiongetRed(row,col){//dosomethingstuffandreturntheredvalueasa
我想添加一个在Ajax调用中指定的外部样式表.我已经找到了一种方法来使用jQuery(参见下面的示例),但是我需要使该方法适应dojoJavaScript框架.JQuery示例$('head').append('<linkrel="stylesheet"type="text/css"href="lightbox_stylesheet.css">');谢谢.解决方法:一旦你
我正在尝试使用dojo.connect将onMouseDown事件连接到图像,如:dojo.connect(dojo.byId("workpic"),"onMouseDown",workpicDown);functionworkpicDown(){alert("mousedown");}类似的代码几行后,我将onMouse*事件连接到dojo.body确实完全正常工作.但是当我点击图像时