这一篇记录一些学习 Atlas (不包含 Control Toolkit 的核心框架部分)碰到的问题点:
1)String.format 函数![]()
Atlas 的客户端脚本提供了 String.format 这个我们在 .NET 编程中非常熟悉也非常常用的函数,基本上实现了和 .NET 一致的功能。也支持对数字、日期的格式化(包括标准 patterns 和自定义 patterns)。
而且 String.format 的格式化,和 .NET 中类似,也是和 Culture 相关的,针对不同的 Cultures 显示不同的格式。如: String.format('{0:d}', new Date(2006, 9, 1)) 在 zh-CN 下显示为 2006/10/1,在 en-US 中显示为 10/1/2006。
另外,Atlas 中的 Sys.StringBuilder 也很好用。
2)atlasglob.axd 及 globalization![]()
此脚本是虚拟的,动态产生。它负责将特定 Culture 的格式定义传递给客户端脚本,用以支持 String.format 的格式化等功能。
但是很重要的是,atlasglob.axd 的默认行为是:根据客户端浏览器中设置的首选语言,来决定到底返回哪个 Culture 的格式定义信息。比如,客户端浏览器首选语言为 zh-CN,则不管当前站点使用何种 Culture,(不受当前 Thread.CurrentCulture 的影响),都会自动将 zh-CN 的格式定义信息传递给客户端。这样可能出现不适当的格式显示。[请参见]
atlasglob.axd 可以接受一个名为 c 的 QueryString。例如如果请求 atlasglob.axd?c=zh-CN,则强制性返回 zh-CN 区域的格式定义信息。
由于 Atlas.js 中默认包含的是 en-US 的格式信息,则,如果网站是 en-US 区域的站点,并且不针对其它区域提供国际化服务,则可以考虑将 ScriptManager 的 EnableScriptGlobalization 设置为 false。如果是非 en-US 的站点,则应该考虑显式包含一个 atlasglob.axd?c=zh-CN 以适应 zh-CN 的日期、数字格式化。
另外,因为 atlasglob.axd 不带参数时,默认取浏览器的首选语言;而浏览器(比如 IE)的语言列表和 .NET 支持的 Cultures 列表并不一致,则可能出现一个 bug,即:如果在浏览器中设置首选语言为一个 .NET 不支持的 Culture 代码,比如 zh,则对 atlasglob.axd 的请求将会出现错误。[请参见]
还有一个另外,今天还发现了一个重要度比较低的 bug:某些预定义的日期 pattern 多了一些单引号。比如 zh-CN 中,'y' 应该解释为 yyyy年M月,而 atlasglob.axd 返回的是 yyyy'年'M'月'。比如,String.format('{0:y}', new Date(2006, 9, 1)) 返回的是 2006'年'10'月' (注意多出来的那几个单引号)。
3)AtlasCompat.js![]()
Atlas 引入了一种手段,如果客户端是非 IE 的 Firefox/Mozilla 系或者 Safari 等浏览器时,自动加入一个脚本 AtlasCompat.js,尝试给这些浏览器的一些 prototype 加以扩展,以实现和 IE “兼容”的 API。
比如:为 Firefox/Mozilla 的元素(Element)扩充 innerText,children 等 IE 脚本中很常用的属性,还有 attachEvent 和 detachEvent 等 IE 独有的方法。
Event 的处理模型在 IE 和 Firefox 之间的差别很大。比如:获取触发事件的对象,在 IE 用 event.srcElement;在 Firefox 需要用 event.explicitOriginalTarget。event 对象的大部分属性在 IE 和 Firefox 之间都是不同的名字,功能实现上也有很多差异。另外,event 对象的获取与传递,也是件比较麻烦的事情。[请参见]
关于 Event 这里多写几点:
(a) 如果你希望访问 event 对象,则建议尽可能使用 attachEvent / detachEvent 的方式挂接事件处理函数。因为在这种情况中,你可以直接按照 IE 中的写法直接访问 event 对象的各个属性。
(b) 在 IE 中: btnSave.onclick = function() { alert('hello'); } 和 btnSave.attachEvent('onclick', function() { alert('hello'); } 是等价的。而在 Firefox 中,它本身没有 attachEvent / detachEvent 方法,Atlas 是使用 addEventListener / removeEventListener 方法实现的。
IE 中 attachEvent 会覆盖掉 btnSave.onclick 原有的函数,或者说 IE 的事件只能挂接一个函数,不能是多个。或者说是“单播”模型。(但可以用变通的方式,将两个函数合并到一起。[请参见])
而 Firefox 的 addEventListener 采用的是“多播”(multicast)模型。使用 addEventListener 可以挂接多个函数到同一个事件上。而像 btnSave.onclick = function() { alert('hello'); }这样的写法,Firefox 的处理方式和 IE 是一样的,也是“单播”的“覆盖”。所以对于 Firefox 来说,上面两种写法是有差别的。
但多数情况中,这个差别是可以忽略不计的。有一种情形,假设画面上有个 Button 控件,单击后,有一个 confirm ,经过确认表单提交。用上面两种写法分别是:
btnSave.onclick = function() { return confirm('Are you sure?'); }
btnSave.attachEvent('onclick', function() { return confirm('Are you sure?'); });
这两种写法在 IE 中都会如你所愿。但在 Firefox,你只能使用前者,后者仍然会提交你的表单。
关于 AtlasCompact.js 总的来说,为熟悉 IE 的编程人员提供一条编写跨浏览器脚本程序的捷径,但由于浏览器间的细节差异,仍然还有不少地方是需要注意的。
(本文所写内容基于 2006 July CTP 版本的 Atlas。)