IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Lotus | Web development  >

实战 iWidget 开发

developerWorks
前一页第 7 页,共 13 页后一页

文档选项

讨论

样例代码


对本教程的评价

帮助我们改进这些内容


Ajax 代理、使用 Ajax 框架与国际化

前面的章节介绍了 iWidget 规范中的基本概念,下面将介绍一些 iWidget 开发中的高级话题。

使用 Ajax 代理

在 iWidget 开发中,经常会使用 XMLHttpRequest 来从服务器端获取数据。 XMLHttpRequest 的一个重要限制是不能进行跨域访问。绕过这一限制的典型做法是在当前域中提供一个代理,由该代理访问其它域的内容。由于这一使用场景非常典型,iWidget 运行环境提供了一个 Ajax 代理。 iWidget 可以通过它来进行跨域访问。

使用 Ajax 代理非常简单,只需要把需要跨域访问的 URL 进行改写,得到一个当前域的 URL,就可以用 XMLHttpRequest 进行访问了。iContext 对象的 io 对象提供了 rewriteURI 方法来完成 URL 的重写。

下面通过一个简单的 iWidget 来说明 Ajax 代理的使用场景。该 iWidget 是一个简易的订阅源(feed)阅读器,可以用来阅读 ATOM/RSS 订阅源。 Lotus Mashups 自带一个订阅源阅读器 iWidget,其功能比较强大。而下面将要实现的这个 iWidget 可以看成是它的简化版。订阅源处理中的一个比较复杂的问题是支持不同格式订阅源,如 ATOM 1.0、RSS 1.0 和 RSS 2.0 等。如果在浏览器中使用 JavaScript 来处理这些 XML 文档,不仅代码逻辑复杂,不同浏览器之间的差异性也会引入额外的复杂度。因此,该 iWidget 的做法是使用 Google AJAX Feed API 来完成订阅源的解析。 Google AJAX Feed API 可以返回 JSON 格式的订阅源内容,在浏览器端处理起来非常方便。清单 13 给出了该 iWidget 的部分 JavaScript 代码,全部的代码见 下载


清单 13. 简易订阅源阅读器部分 JavaScript 代码
 onLoad : function() { 
    var viewBtn = this.byId("view"); 
    var urlInput = this.byId("url"); 
    dojo.connect(viewBtn, "onclick", this, function() { 
        if (urlInput.value) { 
            var feedJsonUrl = 
                "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=" 
				+ encodeURIComponent(urlInput.value); 
            this.loadFeed(feedJsonUrl); 
        } 
    }); 
 }, 
	
 loadFeed : function(url) { 
    var proxiedUrl = this.iContext.io.rewriteURI(url); 
    dojo.xhrGet({ 
        url : proxiedUrl, 
        handleAs : "json", 
        load : dojo.hitch(this, function(data) { 
            if (data.responseStatus == 200) { 
                this.displayFeed(data.responseData.feed); 
            } 
            else { 
                this.displayError(data.responseDetails); 
            } 
        }), 
        error : dojo.hitch(this, function(error) { 
            this.displayError(error.message || " 未知错误 "); 
        }) 
    }); 
 }

清单 13 中可以看到,this.iContext.io.rewriteURI(url) 用来将 Google AJAX Feed API 的请求 URL 转换成由 Ajax 代理处理的 URL,然后使用 Dojo 的 XMLHttpRequest 封装来获取 JSON 格式的内容。图 8 中给出了此 iWidget 在 IBM Mashup Center 中查看“百度国内焦点新闻”订阅源的运行效果图。


图 8. 简易订阅源阅读器的运行效果图
图 8. 简易订阅源阅读器的运行效果图




回页首


使用 Ajax 框架

在当前的 Ajax 应用开发中,Ajax 框架已经成为不可或缺的一部分。成熟的 Ajax 框架可以提高 Ajax 应用的开发效率。 iWidget 的开发也不例外。然而在 iWidget 开发中使用 Ajax 框架并不是那么简单,原因是 Ajax 框架之间可能的冲突以及同一框架的不同版本之间的兼容性问题。目前 Ajax 框架种类繁多,iWidget 开发人员根据需要和熟悉程度,可能选择不同的框架。另外,iWidget 需要运行环境的支持,而运行环境本身也可能使用 Ajax 框架。因此,Ajax 框架的冲突和不同版本的兼容性问题是很有可能发生的。

在 iWidget 中使用 Ajax 框架非常简单,只需要通过 <resource> 元素来引入框架的 JavaScript 代码就可以了。比如使用 <iw:resource uri="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js" /> 就可以加载 jQuery 的 1.3.2 版本。 IBM Mashup Center 1.1 中的 Lotus Mashups 使用的 Dojo 版本是 1.1 。也就是说,如果开发的 iWidget 以其作为目标运行环境,则可以直接使用 Dojo 框架的 1.1 版本。

解决 Ajax 框架的冲突

如果所有以 IBM Mashup Center 1.1 中的 Lotus Mashups 作为目标运行环境的 iWidget 都只使用 Dojo 1.1 的话,那么事情就比较简单了。然而情况并非如此,很多时候你面对的是一个诸多 Ajax 框架和相应不同版本混杂的情况。造成这种情况的原因可能有:

  • 开发人员的技术背景:iWidget 开发人员可能对于其它 Ajax 框架比较熟悉,如 jQuery、MooTools、Prototype 和 YUI 等。他们倾向于选用自己熟悉的框架进行开发。
  • 既有 Web 应用修改成 iWidget:有些时候,已经有了一个 Web 应用,希望能将其修改成 iWidget 。此 Web 应用可能使用其它 Ajax 框架或是 Dojo 的其它版本。比如希望将一个 Dojo 0.4.3 开发的 Web 应用变成 iWidget,运行在 IBM Mashup Center 1.1 中。
  • Ajax 框架的不断更新:主流的 Ajax 框架一直在不断的进行版本更新。你很可能希望在 iWidget 的新版本中使用最新的版本,但是其它 iWidget 可能使用的是同一框架的旧版本。

面对这种情况,解决的办法还是有一些的。

  • 使用 Ajax 框架自己提供的避免冲突的功能。比如 jQuery 提供 jQuery.noConflict() 来解决变量 $ 冲突的问题。
  • 使用 iframe 来隔离。不过额外的 iframe 会使得对其内部 HTML 元素的访问变得复杂,而且有可能造成重复加载同一 Ajax 框架的同一版本的情况。

综合上面的这种情况,最好的选择是使用 Dojo 1.1 来开发你的 iWidget 。如果必须选择其它的 Ajax 框架,需要仔细的考虑可能造成的冲突并找到适合的解决方式。

使用 dijit

在 iWidget 开发中,可能会经常使用 dijit 中提供的组件。一般来说,dijit 支持两种创建方式,一种是由 JavaScript 代码直接创建,如 new dijit.form.Button({label: "hello!",name: "test"});另外一种是在 HTML 中声明,如 <button dojoType="dijit.form.Button">Test</button>。这里需要注意的是,以声明式定义的 dijit 组件,在 iWidget 加载之后不会自动被创建,而是需要显式的调用 dojo.parser.parse 来解析。这里通过一个简单的 iWidget 来说明正确的使用 dijit 的方式。清单 14 中给出了该 iWidget 的定义文件。


清单 14. Dijit 使用示例的定义文件
<iw:iwidget name="DijitSample" 
    xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" 
    supportedModes="view" mode="view" iScope="DijitSample" lang="en"> 
    <iw:resource uri="DijitSample.js" /> 

    <iw:content mode="view"> 
        <![CDATA[ 
            <div id="_IWID_container"> 
                <div dojoType="dijit.ColorPalette" id="_IWID_colorPalette" palette="3x4"">
				</div> 
            </div> 
        ]]> 
    </iw:content> 
 </iw:iwidget>

清单 14中使用声明的方式创建了一个 dijit.ColorPalette 组件。清单 15 给出了该 iWidget 的 JavaScript 代码。


清单 15. Dijit 使用示例的 JavaScript 代码
 dojo.require("dijit.ColorPalette"); 
 dojo.require("dojo.parser"); 

 dojo.declare("DijitSample", null, { 
    byId : function(id) { 
        var idPrefix = this.iContext.widgetId; 
        return document.getElementById("_" + idPrefix + "_" + id); 
    }, 
    
    onLoad : function() { 
        var container = dojo.byId("container"); 
        dojo.parser.parse(container); 
    } 
 });





回页首


国际化

由于 iWidget 实际上是一个小型的 Web 应用,因此 iWidget 的国际化可以参照典型的 Web 应用来进行。 iWidget 既可以包含浏览器端的 HTML、JavaScript 和 CSS 代码,也可以包含服务器端的 Java 代码。对于浏览器端的代码,既可以自己实现相应的国际化支持,也可以使用成熟的 Ajax 框架提供的国际化能力;对于服务器端的 Java 代码,使用 JDK 提供的 ResourceBundle 就可以很好的支持国际化。

由于服务器端 Java 代码的国际化相对比较成熟,下面着重介绍一下浏览器端的国际化支持。比较成熟的 Ajax 框架,如 Dojo,都有比较好的国际化支持。应该遵循这些框架在国际化方面的最佳实践。关于 Dojo 国际化支持的更多信息,请见 参考资料。下面主要介绍 iWidget 与 dijit 在国际化方面的不同。

在 dijit 的模板中,可以使用 ${} 作为占位符来进行变量替换。因此一个典型的国际化做法是把需要本地化的文本都用 ${} 来标识,在 dijit 的 postMixInProperties 方法中把相应的 bundle 添加进去,这样就可以由 dijit 自己来完成文本的替换工作。如 清单 16 所示。


清单 16. dijit 的国际化支持
//dijit 模板
<div>
    <label for="username">
        ${bundle.username_label}
    </label>
    <input type="text" id="username">
</div> 

// 本地化文件:main_zh.js 
( 
{"username_label" : " 用户名 "} 
) 

// 添加 bundle 
postMixInProperties: function() { 
    this.bundle = dojo.i18n.getLocalization("helloworld", "main"); 
}

类似 dijit 模板的这种做法,目前在 iWidget 中并不支持。 iWidget 运行环境不支持对 iWidget 各种模式的 HTML 片断内容的预处理。因此目前 iWidget 的国际化支持有些繁琐,需要在 onLoad 中通过 JavaScript 代码来显式设置本地化文本。如 清单 17 所示。


清单 17. iWidget 的国际化支持
// 查看模式的 HTML 片断内容
<div>
    <label id="_IWID_username_label" for="username">
    </label>
    <input type="text" id="username">
</div> 

// 本地化文件:main_zh.js 
( 
 {"username_label" : " 用户名 "} 
) 

// 设置本地化文本
onLoad: function() { 
    var label = document.getElementById(
        "_" + this.iContext.widgetId + "_username_label"); 
    var bundle = dojo.i18n.getLocalization("helloworld", "main"); 
    label.innerHTML = bundle.username_label; 
 }

清单 17 中可以看到,对所有需要本地化的 HTML 元素,都需要显式的进行设置。





回页首


小结

本章中讨论 iWidget 开发中的 Ajax 代理的使用、Ajax 框架的使用和国际化支持等高级话题。下一章将讨论 iWidget 的打包和调试的话题。





回页首



前一页第 7 页,共 13 页后一页
    关于 IBM 隐私条约 联系 IBM 使用条款