在 WebSphere sMash 中使用 Dojo 开发 Ajax 的 Web 应用程序

WebSphere sMash 是一个适合开发 Web2.0 风格的 Web 开发平台,它的重要目标之一是简化 Ajax 的 Web 开发。而 Dojo 是一个在社区中被广泛使用并且功能强大的 Ajax 工具包。在本文中,将介绍在 WebSphere sMash 中如何使用 Dojo 进行 Ajax 开发以及所提供的相关 Dojo 组件支持。

李 文兵, 软件工程师, IBM 中国软件开发中心

liwb's photo李文兵,是 IBM 中国软件开发实验室的一名软件工程师。目前在 CETI Web 2.0 小组,主要从事 WebSphere sMash 相关的开发工作。http://liwenbing.cn/ 是他的个人主页。



2009 年 9 月 17 日

开始之前

马上下载免费的开发版 WebSphere sMash :
WebSphere sMash Developer Edtion V1.1.1

更多关于 WebSphere sMash 方面的最新技术资源,请参考 WebSphere sMash 产品专题Project Zero 资源中心

本文假设您已经下载了 WebSphere sMash 并且完成了简明教程的学习,或者曾经写过简单的应用程序。您应该熟悉 Ajax 的基本原理和 Dojo 的相关使用方式。

你还需要具备以下先决条件来完成本文的示例应用程序:

  • JDK 5.0 或更高版本。
  • WebSphere sMash 1.0.0.4 或更高版本的命令行环境。
  • 通畅的网络连接来连接 SMTP 邮件服务器。
  • Firefox 3.0 用于启动 AppBuilder

AppBuilder 现在是 WebSphere sMash Developer Edition (开发者版本)的一部分,为 WebSphere sMash 应用程序提供了一个基于 Web 的开发、测试和运行环境。

你可以在命令行输入如下命令打开 AppBuilder:

 appbuilder open

第一次运行时需要一段时间来进行自动配置,完成后将会自动打开一个浏览器窗口,你将看到 AppBuilder 的主界面。

你可以使用如下命令关闭 AppBuilder:

 appbuilder stop

在 WebSphere sMash 中使用 Dojo 进行前端 Ajax 编程

WebSphere sMash 包含了 Dojo 工具集,可以使用 Dojo 进行基于 Ajax 的 Web 前端开发。尽管 Ajax 和 Dojo 并不是 WebSphere sMash 应用所必须的,但是通过使用它们,我们可以构建用户体验更加友好的 Web 应用。

添加 Dojo 到 WebSphere sMash 的应用中

通过向 WebSphere sMash 应用中添加 Dojo 依赖,我们就可以在应用中使用到 Dojo。打开 WebSphere sMash 应用的 config/ivy.xml 文件,添加如下一行。

 <dependency org="dojo" name="dojo" rev="1+"/>

关于更多 Dojo 的信息,请看 参考资料。下面将介绍 WebSphere sMash 为 Dojo 开发提供的相关支持。

使用惯例来构建定制化 Dojo 小部件

惯例是一种习惯用法,它是多年来开发所积累的最佳实践。例如,Ruby on Rails 就得益于“惯例重于配置”的特点。Dojo widget 是将 Web 应用的标准文件进行组合构建一个可以重用的组件,这些文件包括 HTML 和 JavaScript。它非常强大,适合构建复杂、可重用性高的 Web 应用。所以 WebSphere sMash 引入了一个惯例来组织这些定制的 Dojo widget,也就是你可以将这些 widget 的相关文件放在工程结构的特定目录 app/zwidgets/ 中,从而简化工具的整合。比如,这样的惯例能够帮助可视化的 Web 页面编辑器找到你的定制化 widget,并且将其加入到编辑器的工具栏中。

为了使用这样的惯例目录结构,该 WebSphere sMash 应用程序应该添加 Dojo 模块。通过添加 Dojo 模块,WebSphere sMash 应用在遇到 /zwidgets 请求时,将从 app/zwidgets/ 目录寻找相关文件。例如,如果我们需要使用该惯例目录来构建一个叫 x.MyWidget 的 Dojo widget,那么可以创建如下两个文件 :

 app/zwidgets/x/MyWidget.js 

 app/zwidgets/x/templates/MyWidget.html

在使用定制化的 widget 之前,需要进行 Dojo 的模块注册。 对于上面的例子,还需要添加如下一行脚本进行该定制化模块的注册。

 dojo.registerModulePath ("x", "../zwidgets/x");

在上面的例子中,我们使用了相对路径,这样可以保证你的应用不会因为 WebSphere sMash 的 context root(关于 Context Root 的介绍,请参看 参考资料 中 sMash 介绍)的改变而受到影响。

过滤 Dojo 的 preventCache 参数

由于浏览器对于前端请求有不同的缓存策略,所以在使用 Ajax 调用时有可能被浏览器直接使用缓存来返回结果,从而无法得到所需要的数据。因此 Dojo 使用一种反缓存的技术来保证使用 dojo.xhr 的调用请求能够到达服务器,其办法就是在调用的 URL 中添加 dojo.preventCache 这样一个参数。例如,下面 dojo.xhrGet 方法将使调用的 URL 变成唯一,从而防止浏览器的缓存所带来的问题。

dojo.xhrGet( 
{ url: "resources/person", 
   handleAs: "text", 
preventCache: true, 
load: function(response)
    { dojo.byId('info').innerHTML = response; } }
);

当 preventCache 为 true 时,Dojo 将添加该参数到请求的 URL 中,比如 dojo.preventCache=1234567890。这个参数的值是任意的,Dojo 会使用当前的时间戳来保证这个值的唯一。这样,最后发出请求的 URL 大概如下:resources/person?dojo.preventCache=1234567890。应用程序可以通过 /request/params 来访问到所请求的参数,所以如果需要获取 dojo.preventCache,可以使用 GlobalContext 的 API 来获取:

 GlobalContex.zget ("/request/params/dojo.preventCache");

因为它只是客户端的防缓存技术,所以它基本上对于服务端没有意义。但是有时,一些 REST API 可能会对于在 URL 中提供的参数进行一些假设。比如,在 WebSphere sMash 的 Zero 资源模型的 REST API 中,使用请求的参数来进行数据查询。这样,我们就需要在服务器端进行正常业务处理之前过滤掉 dojo.preventCache 这个参数。在 zero.dojo 模块中提供了一个对于 requestBegin 的事件处理来过滤这个参数。在 zero.config 中将 /config/request/params/strip/dojo.preventCache 设置成 true 就可以开启这个功能。

 /config/request/params/strip/dojo.preventCache = true

一般来说,这样就足够了。在开启该过滤功能情况下,使用 /request/params 来访问请求参数时,应用程序将看不到请求 URL 的 dojo.preventCache 参数。当然,该过滤器并不改变 /request/queryString 的值。在默认情况下,每个 HTTP 的请求这个过滤器都会执行。如果需要限定该过滤器在某特定 HTTP 请求上面,你可以在 zero.config 对其事件的响应条件进行配置。如下:

/config/handlers += [
  { "events" : "requestBegin", "handler" : 
  "zero.dojo.filters.DojoPreventCacheFilter.class",
   "conditions" : "/request/path =~ /resources(/.*)?"  }]

Dojo 与 Zero 资源模型共舞

Zero 资源模型(Zero Resource Model,ZRM)提供了一种简单的方式来创建 RESTful 的服务,程序员只需要提供一个简单的资源描述模型,Zero 资源模型将根据该模型定义生成数据源并且支持列表、创建、检索、更新和删除 (LCRUD) 等一系列操作(更多 Zero 资源模型介绍,请参见 参考资料)。WebSphere sMash 针对 Zero 资源模型提供了一组 Dojo 的扩展,以此来简化 Zero 资源模型的 RESTful 服务与 JavaScript 以及 Dojo 小部件之间的交互。

在使用该 Dojo 扩展之前,需要将 zero.dojo 的模块加入 WebSphere sMash 的应用中。

 <dependency org="zero" name="zero.dojo" rev="[1.0.0.0, 2.0.0.0]"/>

使用 zero.resource.DataStore

zero.resource.DataStore 是针对 Zero 资源模型提供了一个对 Dojo Data API 的实现,它支持读、写、通知以及身份标识的 API。通过这个组件,客户端可以使用 Dojo 定义的标准接口来对 Zero 资源模型 进行访问。如下表 1 中列出来该组件的参数:

表 1. zero.resource.DataStore 属性表
属性必须默认值描述
jsId 该属性允许 JavaScript 代码来引用这个组件。比如,为了改变 jsId 为 thegrid 的组件的只读属性,可以这样来使用:thegrid.readonly = true;
resourceCollection 该属性指定了 Zero 资源模型的资源名称。
contextRoot ../resources 该属性指定了当前 Web 页面到 Zero 资源模型的资源相对位置。例如,如果 Web 页面的 URL 为 /people/index.html,那么 contextRoot 属性应该设置成 ../resources。属性的默认值只适合页面在应用的根路径下面。

在 Dojo 中,可以使用两种方式来使用 Dojo 的组件,分别是编程方式以及声明式的方式。下面我们将分别介绍针对 zero.resource.DataStore 的两种使用方式。

编程方式使用 zero.resource.DataStore

因为 zero.resource.DataStore 实现了 Dojo Data API,因此可以在 JavaScript 代码中使用它来操作 Zero 资源模型。它包括创建一个 zero.resource.DataStore 的实例以及调用相关方法从服务器端读写数据。当调用这些方法时,Zero 资源模型的 REST API 将会被调用。这样,它不仅可以作为一个 Dojo data 的一个实现来被其他的 Dojo 的 widget 所使用,同时它还可以当成服务器端数据的一个代理。

下面这个例子将使用 zero.resource.DataStore 来获取 Zero 资源模型的所有数据。这个例子除了使用 zero.resource.DataStorefetch() 方法外,它还需要两个回调函数来进行返回值以及错误的处理。

清单 1. 使用 zero.resource.DataStore 获取数据
var store = new zero.resource.DataStore({ resourceCollection: "resource" });
// Define a callback that fires when all the items are returned.
var gotList = function(items, request) {
   var itemsList = "";
   dojo.forEach(items, function(i) {
      itemsList += dataStore.getValue(i, "name") + " ";
   });
   console.debug("All items are: " + itemsList);
};
var gotError = function(error, request){
   alert("The request to the store failed. " + error);
};

//Invoke the search
dataStore.fetch({
onComplete: gotList,
onError: gotError
});

声明方式使用 zero.resource.DataStore

Dojo 允许在 HTML 页面以声明方式来使用 zero.resource.DataStore。 在下面例子中定义了一个 namevaluepairs 的资源模型:

 { 
   "fields": { 
   "name":{"type": "string"}, 
   "value":{"type":"string"} 
 } 
 }

在定义完该模型后,还需要执行 zero model sync 命令来创建相关的数据库表。当然,你还可以通过 app/models/initial_data.json 来提供一些初始数据。当完成这些后,就可以在 HTML 页面中使用 zero.resource.DataStore 了。首先,需要对 zero.resource.DataStore 进行声明,代码如下:

 <script type="text/javascript"> 
 dojo.require("dojo.parser"); 
 dojo.require("zero.resource.DataStore"); 
 </script>

这样就只需要使用一个 HTML 标签来声明该组件。一般都选择使用 div 标签来进行声明:

 <div dojoType="zero.resource.DataStore" jsId="thestore"
 resourceCollection="namevaluepairs"></div>

这样 jsId 就可以提供给其他的 Dojo 的 widget 进行数据源的绑定。其中属性 resourceCollection 是必需的,用来提供服务器端的资源名称。

使用 zero.grid.DataGrid

zero.grid.DataGrid 是用于操作 Zero Resource Model 数据的一个功能强大的表格控件。它在 Dojo 的 dojox.grid.Grid 控件的基础上进行了扩展,提供了针对 Zero 资源模型的创建、编辑、删除以及排序的功能。下表 2 列出了 zero.grid.DataGrid 的相关属性:

表 2. zero.grid.DataGrid 属性表
属性必须默认值描述
jsId 该属性允许 JavaScript 代码来引用这个组件。比如,为了改变 jsId 为 thegrid 的组件的只读属性,可以这样来使用:thegrid.readonly = true;
resourceCollection 指定 Zero 资源模型的资源名称。当 DataStore 通过参数 store 设置后,该值自动忽略。否则,该值是必须的。
contextRoot ../resources 该属性指定了当前 Web 页面到 Zero 资源模型的资源相对位置。例如,如果 Web 页面的 URL 为 /people/index.html,那么 contextRoot 属性应该设置成 ../resources 属性的默认值只适合页面在应用的根路径下面。
visibleFields 空字符串 通过逗号来列出需要显示的数据列。如果使用空字符串,就表示现时所有的数据量。
readonly false 是否隐藏工具栏,由此使该 DataGrid 为只读
store 提供一个 zero.resource.DataStore 的实例来完成数据的获取以及保存等。
grid 该属性值指明了一个 dojox.grid.Grid 的实例,用来 DataGrid 进行访问。
model 该属性指定了一个 DataStore,用于获取或者更新数据。

注意:在使用 zero.grid.DataGrid 时,需要加载相关的 CSS 样式,从而保证该 Grid 可以被正常显示。如果使用 Dojo 的 soria 主题,需要加载的 CSS 如清单 2 所示:

清单 2. 使用 zero.grid.DataGrid 所需加载的 CSS 样式
<style type="text/css">
@import "/dijit/themes/soria/soria.css";
@import "/dojo/resources/dojo.css";
@import "/zero/grid/DataGrid/DataGrid.css";
@import "/dojox/grid/_grid/Grid.css";
@import "/dojox/grid/_grid/soriaGrid.css";
</style>

下面清单 3 给出了如何在 HTML 中使用 zero.grid.DataGrid

清单 3. 在 HTML 中以标签方式使用 zero.grid.DataGrid
<script type="text/javascript"
src="/dojo/dojo.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("zero.resource.DataStore");
dojo.require("zero.grid.DataGrid");
</script>
<style type="text/css">
@import "/dijit/themes/soria/soria.css";
@import "/dojo/resources/dojo.css";
@import "/zero/grid/DataGrid/DataGrid.css";
@import "/dojox/grid/_grid/Grid.css";
@import "/dojox/grid/_grid/soriaGrid.css";
</style>
<div dojoType="zero.grid.DataGrid" jsId="thegrid"
resourceCollection="namevaluepairs"></div>

上面介绍了 sMash 针对 Zero 资源模型所提供的 Dojo 支持,下面我们将使用上述 Dojo 组件来构建一个 Ajax 应用。


使用 AppBuilder 以及扩展的 Dojo 组件构建 Ajax 应用

下面我们将使用 AppBuilder 来快速构建一个基于 Zero 资源模型 的 Ajax 应用。在这个例子中,我们使用 WebSphere 提供的对 Zero 资源模型的 dojo 扩展组件,并且使用可视化的模型编辑器、表单编辑器以及页面编辑器来构建一个端到端的以数据为中心的 Ajax 应用。

创建一个 Zero 资源模型

首先,需要创建一个 Zero 资源模型,并且和数据库进行初始化。

  1. 在 AppBuilder 中创建一个工程 StudentDetails,如下图 1 所示。
    图 1. AppBuilder 创建工程
    图 1. AppBuilder 创建工程
  2. 在 AppBuilder 中点击 New file,选择 Zero Resource Model using wizard ,在弹出的向导框中输入资源名称为 studentModel。如下图 2 所示。
    图 2. AppBuilder 创建 Zero 资源模型
    图 2. AppBuilder 创建 Zero 资源模型
  3. 点击 Next 为该资源生成资源的处理文件。然后点击 Finish 按钮完成资源的创建。如下图 3 所示。
    图 3. AppBuilder 生成 Zero 资源模型处理文件
    图 3. AppBuilder 生成 Zero 资源模型处理文件
  4. 完成后,AppBuilder 会弹出一个对话框,要求添加 zero.resource 模块到 WebSphere sMash 的应用中。点击 Add 按钮加入该模块的依赖。如下图 4 所示:
    图 4. 添加 zero.resource 依赖
    图 4. 添加 zero.resource 依赖
  5. 在模型编辑器中添加四个数据域。如下图 5 所示:
    图 5. 编辑资源模型
    图 5. 编辑资源模型
  6. 切换到 AppBuilder 的 Console 选项卡,并且执行 zero model sync 命令。

创建一个基于模型的表单

在这个示例中,需要一个表单来进行数据的输入。AppBuilder 提供了可视化的表单设计工具,通过它我们将创建上述模型的一个表单。

  1. 在 AppBuilder 中点击 New File,并且依次选择 Zero Resource Form in /public/zero/forms 以及 New form based on model,在弹出的对话框中输入文件名为 studentForm.json,然后选择 studentModel.json 作为所基于的模型名称。其对话框如下图 6 所示:
    图 6. 编辑资源模型
    图 6. 编辑资源模型
  2. 完成后,AppBuilder 会弹出一个对话框,要求添加 zero.dojo 模块到 WebSphere sMash 的应用中。点击 Add 按钮加入该模块的依赖。如下图 7 所示:
    图 7. 添加 zero.dojo 依赖
    图 7. 添加 zero.dojo 依赖
  3. 创建完毕后,该表单在表单编辑器中显示如下图 8 所示:
    图 8. 添加 zero.dojo 依赖
    图 8. 添加 zero.dojo 依赖

使用表单和表格来创建 Web 页面

下面我们将使用上面创建的 Zero 资源模型 以及表单来创建一个 Ajax 的 Web 页面。

  1. 在 AppBuilder 中点击 New File,并且选择 HTML page in /public, 在弹出的对话框中输入文件名为 index.html,点击确定。
  2. 在页面编辑器的面板中,切换到 Data 选项卡,并且创建一个名为 studentStore 的 ZRM DataStore,如下图 9 所示:
    图 9. 创建 ZRM DataStore
    图 9. 创建 ZRM DataStore
  3. 在面板中,切换到 Create 选项卡。并且创建一个 Zero data grid。设置其 ID 值为 gridId,Data store 为 studentStore,如下图 9 所示:
    图 10. 创建 ZRM DataGrid
    图 10. 创建 ZRM DataGrid
  4. 在页面中创建一个表单组件,设置其 ID 为 theForm, 表单的模型定义为 ./zero/forms/studentForm.json 并且设置 Data Grid Id 为 gridId, 如下图 10 所示 :
    图 11. 创建 Zero Form
    图 11. 创建 Zero Form

使用 “Data Grid ID” 属性可以建立起表单和表格组件之间的相互关系。如果你需要将表单和表格以一种更加灵活的方式关联起来,那么你可以去掉 “Data Grid ID" 中的值,切换到编辑器的 Source 选项卡,加入如下的代码:

清单 4. 对 Form 和 Grid 进行事件绑定
dojo.addOnLoad(function(){
    var zeroGrid = dijit.byId("gridId");
    dojo.connect(zeroGrid.grid,"onSelected",function(){
      var rows = zeroGrid.grid.selection.getSelected();
      var item = zeroGrid.grid.model.getRow(rows[0]).__dojo_data_item;
      dijit.byId("theForm").setValues(item);
     });
});

运行所创建的应用

下面我们将运行所创建的 WebSphere sMash 应用。

  1. 点击 AppBuilder 中的开始按钮来启动该应用程序。
  2. 打开一个页面,并且输入地址为:http://localhost:8080
  3. 如下图 11 所示,你可以使用表单和表格来创建、编辑以及删除数据。
图 12. 示例应用运行界面
图 12. 示例应用运行界面

结束语

本文介绍了在 WebSphere sMash 中如何使用 Dojo 进行 Ajax 开发,并且详细介绍了 WebSphere sMash 针对 Zero 资源模型所提供的 Dojo 的扩展组件以及如何使用它们。最后通过一个例子展示了使用 AppBuilder 以及现有的 Dojo 组件来快速构建一个 Ajax 应用。


下载

描述名字大小
SQL 脚本及测试数据StudentDetails.zip112 KB

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, Web development
ArticleID=428764
ArticleTitle=在 WebSphere sMash 中使用 Dojo 开发 Ajax 的 Web 应用程序
publish-date=09172009