Dojo 1.7作为变化重大的一个版本,已经Release近两个月,而现在已经放出了1.7.2的小版本更新,包括了一些小的fix。让人难以理解的是即使Dojo 1.7已经Release这么久,但是其release notes至今仍
Dojo 1.7作为变化重大的一个版本,已经Release近两个月,而现在已经放出了1.7.2的小版本更新,包括了一些小的fix。让人难以理解的是即使Dojo 1.7已经Release这么久,但是其release notes至今仍然是draft状态。。这也导致了迟迟不能对它进行翻译。看来Dojo社区的那帮老大完全是技术狂,对于文档和社区其他用户的关注还远远不够啊,需要改进。。
尽管Release notes仍然是草稿状态,但也算相对完整,包括了对重要更新的介绍,以及一小部分的升级指南。于是我们对其进行了翻译,希望能帮助大家尽快了解Dojo1.7的新特性,重点关注依然是:AMD。我们同时会保持对英文版release notes的同步更新,大家也可以关注我们的新浪微博:http://weibo.com/dojotoolkit 来获得最新进展。
下面内容翻译自:http://livedocs.dojotoolkit.org/releasenotes/1.7
浏览器支持
经过有效的测试,Dojo1.7支持所有下面列出的浏览器。即使某个浏览器不在列表中,也有可能是支持的,尤其是那些快速release的浏览器(比如Chrome,Firefox)。另外再随后的一些小的release中,Dojo可能会包含一些针对最新浏览器的修复,但是并不一定能保证。
桌面系统
- Firefox 3.6-8
- Safari 5.0-5.1
- Chrome 13-15
- IE 6-9
- Opera 10.50-11.50
- Mobile (dojox/mobile)
iOS 4.x, 5.0 (Mobile Safari) (including all Dijit widgets except Editor, Dialog)
- Android 2.2, 2.3, 3.1
- Blackberry 6
- Mobile compatibility on desktop browsers: IE 8-9, Firefox 3.6-7, Safari 5.0-5.1, Chrome 13-15
基本功能 Dojo Base
AMD
Dojo现在完全支持AMD模块的异步加载,并且同步或者异步加载是可以通过“async”属性进行配置的。
<script data-dojo-config="async: true" src="dojo.js"></script>注意以前被强制加载的模块,现在在异步模式下会被隐含加载。需要确保在require()的参数列表里列出所有模块中需要使用的其他依赖模块(包括再parseOnLoad设为true时需要引入dojo/parser)。比如:
<script src="/dojo/dojo.js" data-dojo-config="parseOnLoad: true, async: true"></script> <script> require([ "dojo/dom", // needed for dojo.byId "dijit/registry", // needed for dijit.byId "dojo/parser", // needed for parseOnLoad to run ... ], function(dom, registry, parser){ // callback when above modules finish loading function update(){ var viewNode = dom.byId("view1"); var view1 = registry.byId("view1"); view1.domNode.innerHTML = "..."; } }); </script>注意,许多Dojo核心和dijit中的模块都在1.7中拆分成更小的模块,以便再异步加载的情况下能支持轻量级的应用。另外,作为这项改动的一部分,Dojo核心中的模块还没有被完美拆分,这项工作将在1.8中继续进行。
Limitations 一些局限性
某些已有的Dojo 1.7之前的模块被设计成只支持同步加载模式。这些模块通过使用同步模式可以继续使用,但如果将async设置为true,即异步模式,则无法工作。Dojo社区正在研究一些可能的控件替换,使得这些功能能够完好的支持异步模式。这是Dojo 2.0之前的工作。
DTL (dojox.dtl - Django Templating):
dojox.dtl就是一个例子,它的设计以同步加载为前提。但这个模块已经被重构以支持异步的AMD加载,但是所有的tag和filter的类库需要被显示的引入。这个限制对于在用户定义的类库和dojox.dtl的默认类库都是一样的。
下面的表格列出了内置的tag和它们对应的模块:
举个例子,如果一个模版使用"{% for" 标签, 那么 'require("dojox/dtl/tag/logic")' 就必须通过应用来加载,从而使得“for”标签能够运行。
下面的表格列出了内置的filter和它们对应的模块:
has.js
Dojo 1.7 引入了一个称之为has()的特性检测API。大多数Dojo核心和dijit模块已经被转换为使用这些特性检查。这项工作将继续在1.8中进行。
dojo.connect
This has been refactored to use the new dojo/on module for event handling. See dojo/on below for more information. 这个API已经被重构为新的dojo/on模块以用于事件处理。参见下面对dojo/on的介绍。
Dojo核心
dojo/on 这个新模块提供了一套新的事件处理系统,包含如下的新功能:
- 事件代理: 事件类型可以包含元素选择符来指定特定的触发对象,例如:on(list, "li:click", onListItemClickHandler);
- 扩展事件:能够创建并使用自定义事件类型作为扩展事件。新的dojox.gesture.*实现了一些扩展事件。
- 可暂停事件:事件处理可以通过on.pausable暂停。
- 单次执行事件:通过on.once使监听函数仅被调用一次。
- (手动)发射事件:浏览器内置事件可以用on.emit(target, "click", event);来(手动)触发。
- 自包含的事件处理对象:on()调用返回的对象包含remove()方法,可直接用于停止对该事件的监听。
- 触摸事件的标准化:触摸事件实现了跨平台(Android,iOS)的标准化。
- 基于has()的功能检测:这使得为特定浏览器打包(移除该浏览器不需要的功能,例如一些针对IE的特殊代码)成为可能。
dojo/query 这个新模块提供了查询DOM结点的功能(类似于dojo.query)。该模块还能加载其他的选择符引擎,例如Sizzle、Slick、Dojo新的轻量级查询选择符引擎、甚至是浏览器内置的选择符查询引擎(但其CSS兼容性最差)。在异步模式下(参见新的Dojo config设置),当dojo/main没有加载时,dojo/query将载入一个采用浏览器自带的qeurySelectAll方法的轻量级引擎,并且只在需要的时候加载完整的acme选择符引擎。dojo/query采用了新的has()方法做功能检测,以便在针对特定浏览器打包时只加载该浏览器所需的最小的选择符引擎。
dojo/data/ObjectStore 如果底层的object store是"Observable"的,这个模块现在将广播该store所产生的所有通知。如果底层的object store在返回结果(results)上有一个observe()方法(通常是用dojo.store.Observable包装),那么dojo/data/ObjectStore就会监听object store中发生的变化,并发送出dojo.data通知事件。
Parser(解析器) Dojo的页面解析器在新版本中得到了进一步增强。现在您可以区分浏览器自带的捏制属性和Dojo对象的属性,将内置属性直接写在html标签中,而将Dojo对象属性都写到data-dojo-props属性里,例如:
<input data-dojo-type="dijit.form.TextBox" name="dept" data-dojo-props="scrollOnFocus: true"/>
解析器还支持声明方式创建dojo.on和object.watch的监听函数。方法是加入type="dojo/on"或type="dojo/watch"的<script>标签。下面是一个type="dojo/on"的例子:
<button data-dojo-type="dijit.form.Button"> Click Me! <script type="dojo/on" data-dojo-event="click" data-dojo-args="e">console.log("I was clicked!");</script> </button>
一个type="dojo/watch"的例子(基于dojo/on):
<button data-dojo-type="dijit.form.Button">Click Me! <script type="dojo/on" data-dojo-event="click" data-dojo-args="e"> dijit.byId("textBox1").set("value", "New Value!"); </script> </button> <div data-dojo-type="dijit.form.TextBox" id="textBox1" data-dojo-props="value: 'Old Value'"> <script type="dojo/watch" data-dojo-prop="value" data-dojo-args="prop,oldValue,newValue"> console.log("Prop '"+prop+"' was '"+oldValue+"' and is now '"+newValue+"'"); </script> </div>
注意: 目前不再支持type="dojo/watch"的<script>标签的prop属性,解析器只能识别data-dojo-prop属性。
提醒: 当使用异步模式时,您需要显示地加载dojo/parser模块以确保parseOnLoad: true能够生效。(在非异步模式下,dojo/parser将会自动加载,但会出现一条“不推荐”警告。从技术角度而言,dojo/parser是不被自动加载的,但在1.7之前,它在许多情况下都会被自动加载,这是因为dijit/_Templated依赖于它,而许多widget都依赖dijit/_Templated。
dojo/touch 这个模块提供了一组统一的触摸事件:"press | move | release | cancel"。这些事件能够兼容大量设备(包括桌面设备)。
其原理非常简单,"press | move | release | cancel"分别对应于:
- "touchstart | touchmove | touchend | touchcancel" (触摸屏设备W3C Touch Events Specification)
- "mousedown | mousemove | mouseup | mouseleave" (桌面设备)
dojo/touch基于 dojo/on ,下面的示例在桌面环境和触摸屏设备(包括Android 2.2/2.3以及针对1.7的iOS3+)上都能正常工作:
更详细的资料请参考 dojo/touch doc
Dijit 针对桌面浏览器的开发的Web应用经常在手机浏览器上运行失败。为避免这种情况,Dojo从1.7开始,除了Editor控件以外的dijit控件增加了对主流手机平台(苹果、安卓以及黑莓)的基本支持。
另外,在手机平台上运行Dialog控件时,必须把draggable参数设为false,以确保Dialog的关闭图标工作正常。将在未来的版本中修复这个bug。
_WidgetBase
_WidgetBase类添加了getParent()方法,可以使用该方法得到当前控件的父容器控件,不论父控件是否有isContainer标记。同时isContainer标记已被废弃。
_TemplatedMixin, _WidgetsInTemplateMixin
新增了两个粒度更小的模板聚合类:_TemplatedMixin和_WidgetsInTemplatedMixin。在控件模板内部不包含其他控件时,使用_TemplatedMixin作为控件的模板类;如果空间模板内部包含控件时,除使用_TemplatedMixin外,还要添加_WidgetsInTemplateMixin作为控件的模板类。原先的模板类_Templated功能以及接口保持不变。
_setXXXAttr
_setXXXAttr方法作为函数在之前的版本可以设置对象属性,或者触发设置属性时要被执行的逻辑。在新版本中_setXXXAttr还能被作为单纯的对象使用,以下举例说明:1._setTabIndexAttr: "focusNode"
该语句会把对象tabIndex属性直接添加到控件的focusNode上:this.focusNode.tabIndex;
2._setTitleAttr: { node: "titleNode", type: "innerHTML" }
该语句会使用title属性对控件的titleNode.innerHTML进行赋值,如myWidget.set(“title”, “hello world”)会给myWidget的titleNode.innerHTML赋为hello world。
这样就替换了原本的attributeMap的功能,attributeMap参数已被废弃并将在2.0版本中删除。
dijit/focus, dijit/place, and dijit/popup
focus、place以及popup三个模块从dijit/_base移到了dijit目录下,所以这三个模块都不会在加载dijit时默认加载。也就是说,控件可根据需要选择性的加载这三个模块,避免增加不必要的代码。
There are a few API changes in the top level modules compared to the ones in dijit/_base (although for backwards compatibility the modules in dijit/_base maintain their old API):
作为可独立加载的模块,focus、place以及popup中的方法也做了相应的修改:
• popup.around()替换了dijit.popup.placeAroundElement(),同时参数也从{BL:”TL”,…}变为更人性化的[“before”,”after”,…];
• dijit/focus不再包含选择(selection)相关的代码,只包含focus相关代码;
• dijit/focus提供了watch()和on()方法以检测控件的获得焦点事件;
• dijit/_base/popup中一些原先可接受节点或控件作为参数的方法,在新版本中只接受控件参数。
另外,dijit/popup模块只能通过新的AMD API加载,如:
require(["dijit/popup"], function(popup){ popup.open(...); });
CalendarLite
dijit.CalendarLite是针对手机平台开发的新日历控件。其基本功能与Calendar相同,不过不支持键盘操作,也不包含月份下拉列表。
ComboBox, FilteringSelect
ComboBox和FilteringSelect为应用dojo.store(新的数据读写接口)做了相应的修改,同时依然支持旧的dojo.data 接口。
DojoX
图表 (Charting)
Action2d 包已经包括了新的缩放(Zoom)和摇摆(Pan)功能,以及数据指示和交互功能。它们使得用户能用鼠标或者触摸手势来与图表进行交互。
在移动设备方面采用各种方法类提高性能。大多数图表类型都支持新的允许缓存参数,能够允许缓存和重用gfx图形。
使用AMD模块格式
通过两个BidiSupport类来支持图表的双向文字.(一个类用于dojox.charting, 一个类用于dojox.charting.widget) 在程序中为了支持双向文字必须请求这些类。
仪表 (Gauges)
仪表从原来位于dojox.widget移动到了新的命名空间dojox.guages
加入了几种新的指示器来用于创建用户自己的仪表,例如文字指示器可用于以文字的形式绘出仪表的刻度值。
创建圆形仪表时能够选择顺时针或者逆时针走向。
改进了圆形刻度的标签布局
仪表现在能够支持在移动设备上的触摸交互
Dojox.gauges使用AMD 模块格式
可以直接获得三种的新内建仪表:GlossyHorizontalGuage, GlossyCircularGauge和GlossySemiCircularGauge
地图 (GeoCharting Map)
Dojox.geo.charting模块实现了多种改进:包括tooltip管理,当更改数据列时模拟颜色变化
提供新的数据源结构,以及地图元素和数据源元素之间的数据绑定
通过安装专门的交互类,允许交互式的通过鼠标或者触摸手势来对地图进行缩放和摇摆
通过新的地图 Dijit控件将非dijit dojox.geo.charting 地图控件封装,从而实现更轻松的整合
使用AMD模块格式
Gfx
现在每个形状都由一个关联的唯一的id(Shape.getUID())来标识. 此外,新的dojox.gfx.shape.byId() 函数将返回与此形状关联的id。
添加了输入事件来支持画布提供者。这个功能缺省是打开的,可以通过设置dojoConfig中的“canvasEvents”标志来关闭之。
鼠标事件指向的Gfx形状可以通过事件本身的“gfxTarget”属性来获取:
group.connect("onmousedown", function(evt){ var s = evt.gfxTarget; ... });
Gesture
基于dojo/touch和dojo/on,这个新的模块提供了一种机制,让我们可以实现能良好运行在不同的设备上的手势行为,包括桌面和各种各样的可触摸设备。
dojox/gesture/Base
一个用于实现各种手势行为的抽象基类,它主要用于:
• 绑定 on() 监听器用于处理手势事件,如tap, taphold, doubletap
• 监听底层事件并执行不同阶段动作 - 'press'|'move'|'release'|'cancel'
• 基于on() 接口触发手势事件
实现一个手势动作只需要扩展和覆写适当阶段的处理函数即可 - press() | move() | release() | cancel() 用于识别和触发手势
dojox/gesture/tap(只适用于单触摸)
• 提供公共的tap手势方式,包括tap, tap.hold and tap.doubletap
• 用户可配置 e.g. Tap.hold的阈值, tap.doubletap有效半径
dojox/gesture/swipe(只适用于单触摸)
• 提供公共的swipe手势方式,包括swipe, swipe.end
touch & gesture demo 展示了基于dojo/touch 和dojox/gesture.的dijit/form/HorizontalSlider 控件和dojo/dnd 是如何运行在 iOS4+ 的操作系统上的。 除了一个tap手势, 这个示例也展示了基于多触摸实现一个新的旋转的手势是非常容易的。
更多详细信息请参考 dojox/gesture doc .
Grid
DataGrid/EnhancedGrid/TreeGrid/LazyTreeGrid
• 1.7 修复的大量的缺陷和问题, 更多详细信息请参考 defect list
下一代Grid
• 进行中的项目:dgrid 和 gridx 正密切合作,目标下一代Grid
Mobile
Dojo Mobile 是目前市场上一流的移动web开发库, 支持AMD加载方式和新的Build模式,现在有一个专门为Dojo移动开发库制定的新的指导手册和详细的API文档Dojo Mobile Reference Guide
• 加入了新的BlackBerry OS6 皮肤,迄今为止,已支持以上列表中所有的移动设备和操作系统。
• dojox.mobile.deviceTheme是一个皮肤加载器,他会识别访问的设备并加载相应合适的皮肤。
• 新的SpinWheel控件让你可以通过该控件设置和选择相应的值,支持两种方式:SpinWheelDatePicker 和SpinWheelTimePicker,
• 新的卡盘(Carousel)控件,他会显示一个图像列表,用户可以从中选择相应的元素。
• 新的RoundRectDataList 和EdgeToEdgeDataList 控件,他们基于RoundRectList 和EdgeToEdgeList控件,支持数据驱动。
• 新的PageIndicator控件,他会显示当前的页号,并配合以小圆点。该控件可以和 SwapView 或者Carousel合用。
• 加入了一些新的动画效果: Dissolve, Flip2, Cover, Reveal, Slide Vertical, Cover Vertical, Reveal Vertical, Swirl, Zoom In/Out, and Scale In/Out.
• 将FlippableView 控件更名为SwapView.
• dojox.mobile 现在均基于 AMD 模式
• TextBox 控件从原来的 mobile/app/ 包下面移动到 mobile/包下面。
• 新的Tooltip 控件会弹出一个容器,该容器可包含简单文本或另一个新的控件。
• 新的Overlay控件从下方滑入,完成后则向下方滑出。
• 新的Opener控件加入了实时的屏幕大小侦测器,并配合以使用Tooltip控件(针对大屏的移动设备)和Overlay 控件(针对小屏的移动设备)。
• 新的ComboBox 控件(实验阶段) 支持文字搜索(同dijit.form.ComboBox)
• 新的ExpandingTextarea 控件支持纵向的基于文字内容的伸展和收缩。
• 新的Slider 控件使用户能够很方便的通过触摸/手势来控制其值。
• 新的HTML 表单控件包装器 (Textarea, CheckBox, RadioButton) 使得表单可以和各种dijit的控件联合使用,如:container/dialog 等等控件.
Limitations:
• 很多动画效果是基于CSS 3 transition / animation的,并且他们的行为依赖于具体的移动设备和移动浏览器,所以有些动画效果在 Android 和BlackBerry等移动设备上并不是很流畅。
• ScrollableView 在HTC Android设备上经常会被“冻死”, 如:HTC Evo, HTC Desire,等等,尤其是当你在屏幕已经在滑动的同时,进行另外一个滑动操作。这是JavaScript 的一个缺陷,目前还没有好的解决方案。
• 在Android设备上,当你通过触摸的方式试图选中ScrollableView中一个表单中的一个输入框或者按钮时,会发现有时无法让该控件获取焦点,可能你需要多试几次才行。
MVC
dojox.mvc 是一个新的实验性质的dojox 项目,基于MVC的思想,实现Client段的Model,Control和View三层的分离,使得基于Dojo开发诸如企业级应用,IT应用,CRUD 应用,主从模式应用等等的复杂应用变得更为简单。这个release包括:
• 一流的数据模型,能与data stores直接交互
• 能让控件或者可视化组件绑定到数据模型的数据绑定功能
• MVC 还包括分组(用于分级数据) 和重复(用于重复的数据,如:数组)
• 还有诸如 数据绑定输出和数据驱动的UI生成器的MVC控件
• 可以基于以上MVC模型构造出各种各样的富数据模式示例
OpenLayers Maps
• 新的dojox.geo.openlayers 工具包基于已开源的OpenLayers库,详细可 (参见 http://www.openlayers.org/ ).
• 用户可在以OpenLayers地图为背景的区域内添加添加 地图相关Gfx 形状或者控件.
• 基于AMD 的形式.
Migration
升级指南加载器,构建器相关
<script>
在以前的版本中,可以通过<script>标签来加载模块(module)和layer, 例如
<script src="/mysite/app/MyWidget.js">尽管这种用法在1.7的构建后的build中依然有效,但将不推荐使用,并且在未构建的源代码版本中将无法使用,强制使用会导致程序出错同时控制台中会出现"multipleDefine" 错误。在这种情况下应使用dojo.require(), 例如
dojo.require("app.MyWidget");或者直接用最新的AMD的require() API全局变量
在以前的版本中,可以在一个模块中通过如下方式定义全局方法:
dojo.provide("my.module"); function myOnClick(){ ... }
然后在1.7中,所有模块都在一个封闭的方法中被解释(evaluated),上述的方法将只存在于对应的闭包(closure)中而非全局空间中。如果需要在模块中定义全局空间中的方法或变量,应使用dojo.global:
dojo.provide("my.module");dojo.global.myOnClick = function(){ ... }
关于定制压缩Build的注意事项
selectorEngine
值得注意的是acme 查询引擎(acme query engine) 默认将不再包含在压缩后的dojo.js中,因此在dojo/query 或 Dojo base 加载时会导致额外的网络请求以获取。如果希望将acme query engine包含到压缩后的dojo.js中,可以在build profile中定义selectorEngine: "acme" 或直接在build命令行中添加selectorEngine=acme 参数,也可以参考Dojo 1.7.1中自带的standard.profile.js
关于更多selector engines的信息,请参考dojo/query documentation.
dijit/_base
以前的版本中,在压缩时dijit/_base 会自动导入其所依赖的dijit/_Widget模块. 在1.7版本中dijit/_Widget模块只会在非AMD(向后兼容)模式中被导入。因此Dojo构建器不再认为dijit/_base依赖于dijit/_Widget。
为了避免可能额外的网络请求,建议在上述情况下将dijit/_Widget作为显示的依赖添加到build profile中。
跨域模式中使用本地模块 Dojo 1.7 有一个局限性,在非AMD向后兼容的模式下,跨域访问即dojo.js是从第三方域加载的轻快下,Dojo 无法加载使用非AMD即dojo.require形式的模块。目前唯一的办法是将本地模块改写成新的AMD语法,或者在这种情况下避免使用跨域访问,请参见 defect #14459. debugAtAllCosts 在1.7版本中,djConfig 中的debugAtAllCosts 参数将无法使用,可以使用如下相应的方式替换: 将应用转成新的AMD语法并使用异步加载模式(async:true), 所有通过标准AMD加载的模块便可进行调试 通过运行压缩build, 将所有非AMD模块转成新的AMD 语法。 注意:在将应用转换正最新的AMD语法时可能会需要额外的时间例如来移除旧的API - dojo.getObject 等,尽管这可能会比直接压缩一个build费时,但将能获得1.7带来的全面改进特性。