使用移动设备是最流行的 Web 浏览方式之一。随着移动设备用户的不断增加,有必要开发更多的移动应用程序和移动友好型网站。针对不同的平台(比如 iOS、Android 和 Blackberry OS 等)来创建本地移动应用程序存在着难度,能够在某种设备上工作的代码不一定能够运行在另一种设备上,甚至在由不同厂家生产的有着相同 OS 实现的设备上也是如此。
使用 Dojo Toolkit (dojox.mobile),您可以创建构件来模拟那些最流行的移动设备界面。在本文中,您会了解到如何使用 Dojo Toolkit 来创建 Web 移动应用程序,以及使用从服务器请求的数据来动态地更新应用程序的内容。IBM® Workload Deployer (IWD) 具象状态转移 (REST) 应用程序编程接口 (API) 用于获取应用程序属性,在本文中也有讨论。
在本文中,我会创建一个名为 IWDMobile 的 Web 移动应用程序。该应用程序有一个简单的需求:列出并显示与从服务器提取的数据相关的信息。
该应用程序由一个 HTML 文件 IWDMobile.html 构成,该文件是应用程序的核心。该文件使用:
- Dojo 来创建模拟移动用户界面的构件
- HTTP 方法来查询服务器
IBM Workload Deployer REST API
IBM Workload Deployer REST API 提供 REST 调用来管理 Workload Deployer 设备。本文使用 GET /resources/applicationPatterns,这是一个 REST 调用,用于获取有关虚拟应用程序模式的信息。虚拟应用程序模式拥有诸如名称、ID 和创建者之类的属性。
基于本文的目的,IWDMobile.html 这一文件被放在某个与 IBM Workload Deployer 共享网络的服务器的公共文件夹下面。
您的 HTML 文件可以通过两种方式来访问 Dojo。它可通过一个公共的内容交付网络(或 CDN,比如 Google 和 AOL)来访问可用的 Dojo,或是从您自己的网站中获取 Dojo。本文引用的是 Dojo 1.7 的功能,不过由于 Dojo 1.7 尚未发布,还不能通过公共的 CDN 来使用,因此可以从 Dojo Toolkit 网站上下载 Dojo 1.7 最新版本的副本,并把它解压在 /public 目录下面。(参阅 参考资料 获取下载 Dojo Toolkit 的链接。)
您应该要有如下的目录结构:
- /public/IWDMobile.html
- /public/dojo1.7/
考虑使用下面的 HTML 模板来开始您的 Web 移动应用程序的创建:
清单 1. 应用程序的 HTML 模板样例
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta name="viewport"
content="width=device-width,
initial-scale=1,
maximum-scale=1,
minimum-scale=1,
user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>IWDMobile</title>
<link
href="dojo1.7/dojox/mobile/themes/iphone/iphone.css"
rel="stylesheet" />
<script type="text/javascript"
src="dojo1.7/dojo/dojo.js"
djConfig="isDebug:true, parseOnLoad:true">
</script>
<script language="JavaScript" type="text/javascript">
dojo.require("dojox.mobile.parser");
dojo.require("dojox.mobile");
dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
</script>
</head>
<body>
</body>
</html>
|
Dojo 语句是 HTML 文件的头部内容的一部分。这些语句加载了 Dojo 库以及解析信息所需的 Dojo 类。也定义了 CSS 主题和特定于移动设备的 META 标签。若要了解更多关于特定于移动设备的 META 标签的内容,请参阅后面 参考资料 中列出的 “特定于 Apple 的移动 Meta 标签”。
IWDMobile 需要一个视图来列出从服务器获取的虚拟应用程序模式。在本文中,用到两个视图。
- 第一个视图存放虚拟应用程序模式的名称。
- 第二个视图存放虚拟应用程序模式的属性。
当某个虚拟应用程序模式的名称被选中时,它的属性就应该被显示出来。
Dojo 所提供的构件和方法符合 IWDMobile 的需求。该应用程序需要用到的构件包括:
- Dojox.mobile.ScrollableView(表示移动设备屏幕的容器)
- Dojox.mobile.Heading(表示一个导航栏)
- Dojox.mobile.RoundRectList(项的容器)
- Dojox.mobile.ListItem(表示列表项)
更新文件的主体部分以适应这些构件。
清单 2. HTML 模板样例的主体部分
<body>
<!-- Application pattern view -->
<div id="appPatterns" dojotype="dojox.mobile.ScrollableView">
<h1 dojotype="dojox.mobile.Heading" label="Patterns"></h1>
</div>
<!-- Application pattern info view -->
<div id="appPatternsInfo" dojotype="dojox.mobile.ScrollableView">
<h1 dojotype="dojox.mobile.Heading"
label="Pattern Information"
back="Patterns"
moveto="appPatterns"></h1>
<ul id="patternInfoList" dojotype="dojox.mobile.RoundRectList">
</ul>
</div>
</body>
|
需要用到两个 JavaScript 函数:
- 第一个函数从服务器获取数据
- 第二个函数提取虚拟应用程序模式的属性
第一个函数 getApplicationPatterns() 需要向服务器发送一个 GET 请求,解析服务器的响应,创建一个列表容器,使用存放了虚拟应用程序模式名称的列表项来填充列表容器,为每个列表项添加一个点击按钮 (on-click) 事件,并把列表容器添加到 appPatterns 视图中。
第二个函数 getPatternInfo(virtAppPatternObject) 使用一个虚拟应用程序模式对象作为参数。该函数需要提取该虚拟应用程序模式对象的属性,创建存放虚拟应用程序模式的属性值的列表项,并把这些列表项添加到 patternInfoList 列表容器中。
getApplicationPatterns()
下面的代码段反映了这一函数背后的想法。
- 第 1 步:
GET /resources/applicationPatterns请求。
清单 3. 从服务器获取数据
dojo.xhrGet({
url :"https://iwd.server.com/resources/applicationPatterns",
handleAs : "json",
headers : {
'X-Deployer-API-Version': '3.0',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
load : function(response) { },
error : function(e) { }
});
|
- 第 2 步:将服务器的响应保存在一个新的变量中。
清单 4. 保存来自服务器的数据
var sdata = response; |
- 第 3 步:创建一个存放应用程序名称的列表容器。
dojo.mobile.RoundRectList 创建了一个名为 applicationPatternsList 的新列表容器。
清单 5. 创建一个列表容器
var appPatternListContainer = new
dojox.mobile.RoundRectList({id:"applicationPatternsList"});
|
- 第 4 步:将响应中的每个元素的项添加到第 3 步的列表容器中。
dojox.mobile.ListItem 创建列表项元素。每个元素都分配了一个标签和一个 moveTo 属性。标签是列表项要显示的文本,在本例中是虚拟应用程序模式的名称。moveTo 属性告诉应用程序,如果该项被选中的话,应该打开哪个视图。在本例中,要打开的是 appPatternsInfo 视图。
addChild 将每个列表项都添加到 appPatternsListItem 这一列表容器中。
for-loop 确保将每个列表项都添加到了列表容器中。
清单 6. 将项添加到列表容器中
for(var i in sdata){
var name = sdata[i].app_name
var appPatternListItem = new dojox.mobile.ListItem({
label: name,
moveTo: "appPatternsInfo"
});
appPatternListContainer.addChild(appPatternListItem);
}
|
- 第 5 步:为列表中的每个项添加一个点击按钮事件。当单击列表中的某个项时,事件会在
appPatternsInfo视图中显示该项的信息。
dojo.connect 将点击按钮事件与列表项连接起来。
dojo.hitch 执行带有 sdata[i] 参数的 getPatternInfo 函数。
for-loop 确保为每个列表项分配了一个点击按钮事件。
清单 7. 添加点击按钮事件
for(var i in sdata){
dojo.connect(appPatternListItem,
"onclick",
dojo.hitch(null,
getPatternInfo, sdata[i]));
}
|
- 第 6 步:添加一个列表容器到
appPatterns视图中。
dijit.byId 查找 appPatterns 这一视图构件。
addChild 将 appPatterListContainer 构件添加到 appPatterns 视图。
清单 8. 将列表容器添加到视图中
dijit.byId("appPatterns").addChild(appPatternListContainer);
|
getApplicationPatterns JavaScript 函数的最终代码看起来像这样:
清单 9. 从服务器获取数据的最终代码
function getApplicationPatterns(){
// Send a request to the server
dojo.xhrGet({
url : "https://iwd.server.com/resources/applicationPatterns",
handleAs : "json",
headers : {
'X-Deployer-API-Version': '3.0',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
load : function(response) {
// Server responds with information in json format
var sdata = response;
// Create the list container that will hold application names
var appPatternListContainer = new
dojox.mobile.RoundRectList({id:"applicationPatternsList"});
// Add a new item to the list container for each element
for (var i in sdata){
// Create and populate the list container (app names)
var name = sdata[i].app_name
var appPatternListItem = new dojox.mobile.ListItem({
label: name,
moveTo: "appPatternsInfo"});
// Add the newly created item to the list container
appPatternListContainer.addChild(appPatternListItem);
// Attach an "onclick" event for each item on the list.
// When the item is clicked, it will display information
// about it on a new view (in this case appPatternsInfo)
dojo.connect(appPatternListItem,
"onclick",
dojo.hitch(null,
getPatternInfo, sdata[i]));
}
// Add list container to the appPatterns view
dijit.byId("appPatterns").addChild(appPatternListContainer);
},
error : function(e) {}
});
}
|
getPatternInfo(virtAppPatternObject)
下面的代码段反映了该函数背后的想法。
- 第 1 步:清空列表容器。
destroyDescendants 销毁了指定构件的直接子构件和间接子构件。您会希望确保有一个干净的开始,将之前存放在 DOM 元素中的所有数据都删除掉。
清单 10. 清空列表容器
dijit.byId("patternInfoList").destroyDescendants();
|
- 第 2 步:创建虚拟应用程序模式属性的列表。
清单 11. 创建虚拟应用程序模式属性的列表
var listItemLabels= ["Application name",
"Application id",
"Application type",
"Content MD5",
"Content type",
"Creation time",
"Creator",
"Last modified",
"Last modifier",
"Collection"];
|
- 第 3 步:从虚拟应用程序模式对象中获取属性值。
清单 12. 从虚拟应用程序模式对象中获取属性值
var listItemInfo = [virtAppPatternObject.app_name, virtAppPatternObject.app_id, virtAppPatternObject.app_type, virtAppPatternObject.content_md5, virtAppPatternObject.content_type, virtAppPatternObject.create_time, virtAppPatternObject.creator, virtAppPatternObject.last_modified, virtAppPatternObject.last_modifier, virtAppPatternObject.Collection]; |
- 第 4 步:创建列表项并将它们添加到
patternInfoList容器中。
dijit.byId 查找 patternInfoList 这一视图构件。
dojox.mobile.ListItem 创建列表项元素。每个元素都分配了一个标签和一个 rightText 属性。标签是显示在列表项左端的文本内容,在本例中,是属性的名称。rightText 属性是显示在列表项右端的文本内容,在本例中,是属性的值。
addChild 将列表项添加到 patternInfoList 视图中。
清单 13. 将列表项添加到容器中
for(var j in listItemLabels){
// Populate list container with application properties and values
var list = dijit.byId("patternInfoList");
var appPatternInfo = new dojox.mobile.ListItem({
label: listItemLabels[j] ,
rightText: listItemInfo[j]
});
list.addChild(appPatternInfo);
}
|
getPatternInfo(virtAppPatternObject) JavaScript 函数的最终代码看起来像这样:
清单 14. 提取虚拟应用程序模式属性的最终代码
function getPatternInfo(virtAppPatternObject){
// Clear list container before attaching information to it.
dijit.byId("patternInfoList").destroyDescendants();
// List of application's information
var listItemLabels= ["Application name",
"Application id",
"Application type",
"Content MD5",
"Content type",
"Creation time",
"Creator",
"Last modified",
"Last modifier",
"Collection"];
// List of application's values
var listItemInfo = [virtAppPatternObject.app_name,
virtAppPatternObject.app_id,
virtAppPatternObject.app_type,
virtAppPatternObject.content_md5,
virtAppPatternObject.content_type,
virtAppPatternObject.create_time,
virtAppPatternObject.creator,
virtAppPatternObject.last_modified,
virtAppPatternObject.last_modifier,
virtAppPatternObject.Collection];
// Create and populate application's information
for(var j in listItemLabels){
// Populate list container with application properties and values
var list = dijit.byId("patternInfoList");
var appPatternInfo = new dojox.mobile.ListItem({
label: listItemLabels[j] ,
rightText: listItemInfo[j]
});
list.addChild(appPatternInfo);
}
}
|
如前所述,IWDMobile.html 是应用程序的核心,它存放了 HTML 代码、Dojo 语句和创建 IWDMobile 应用程序所需的 JavaScript 类。您可以 下载 IWDMobile.html 的最终版本。
通过 URL 打开 IWDMobile.html 文件。例如,https://iwd.server.com/IWDMobile.html。
图 1 展示了最初的视图(模式视图),该视图列出虚拟应用程序模式的名称。单击列出的任一项内容就会重定向到模式信息视图,该视图显示被选中项的详细信息。
图 1. 模式视图
图 2 显示了虚拟应用程序模式 “Blank application” 的详细信息。
图 2. 模式信息视图
在本文中,你已了解了如何使用 Dojo Toolkit 来创建模拟移动用户界面的 Web 移动应用程序,了解了如何使用从服务器请求的数据来动态地更新应用程序的内容。做法是多种多样的,现在就取决于您如何决定应用程序的行为了,祝您好运!
感谢 Andy Dingsor 和 Yoshiroh Kamiyama 在撰写本文期间所做的反馈。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| 本文的 HTML 文件样例 | IWDMobile.zip | 2KB | HTTP |
学习
- 有关其他背景知识,请阅读 “Get
started with Dojo Mobile 1.7”(developerWorks,2011 年 8 月)。
- 在 developerWorks 上了解更多关于 IBM Workload Deployer 的内容。
- 了解 特定于 Apple 的移动 Meta 标签。
- 在 developerWorks Web 开发专区 中,可以找到数百篇 how-to 文章及教程、下载内容、讨论论坛,以及为 Web 开发人员提供的其他丰富的资源。
-
加入免费的 developerWorks Live! 技术加油站,快速了解 IBM 产品和工具,以及 IT 行业趋势。
- 观看 developerWorks 演示中心,包括面向初学者的产品安装和设置演示,以及为经验丰富的开发人员提供的高级功能。
获得产品和技术
- 从 Dojo Toolkit 网页上下载最新版本的 Dojo 1.7。
-
IBM
Workload Deployer 允许您将智能 SOA 中间件和服务扩展到私有云中。
- IBM
WebSphere
Application Server Feature Pack for Web 2.0 and Mobile 包含 IBM Dojo 1.7 Toolkit、新的移动和富 Internet 应用程序 (RIA) 构建块,以及一个基于 Dojo 的图表组件。与配备的 Rational 工具一起使用,该功能包有助于您先开发出用于桌面浏览器的 WebSphere 应用程序,然后再修改它们并将它们部署到移动设备上。请点击这里 了解更多内容。
-
以最适合您的方式 评估 IBM 产品:下载产品试用版,在线试用产品,在云环境下使用产品,或者在 SOA 沙箱 中花费几个小时来学习如何高效实现面向服务架构。
讨论
- 加入 IBM developerWorks 社区。查看开发人员推动的博客、论坛、组和 wiki,并与其他 developerWorks 用户交流。
