您的位置:首页 > 产品设计 > UI/UE

使用 Dojo TreeGrid 管理 WebSphere Process Server 工作流为数据创建 Web 2.0 风格的 UI

2012-01-07 21:26 896 查看
简介

如果您正在使用 IBM WebSphere Process Server,那么肯定了解它的许多特性。在本文中,学习如何使用强大的 Dojo
TreeWidget
来管理 WebSphere Process Server 中的流程。本文通过一个例子探索如何处理分层数据,并通过创建 Web 2.0 风格的用户界面(UI)来管理数据。

您还可以通过下面的 下载列表 下载本文的样例代码。

回页首

Dojo TreeGrid

dojox.Grid 是 Dojo 小部件的重要组件之一,它允许您轻松地操作和呈现远程数据和来自 web 页面的数据。
TreeGrid
同时具备 dijit.Tree 和 dojox.Grid 的优点:它能够像 dijit.Tree 一样处理分层数据结构,也能够像 dojox.Grid 一样呈现数据。与 dojox.Grid 一样,
TreeGrid
可以通过两种方式来构建
TreeGrid
:声明式或编程式。图 1 显示了一个简单的
TreeGrid


图 1. 简单的 Dojo TreeGrid



架构

TreeGrid
采用 Model-View-Controller (MVC) 设计模式,如下所示。

图 2. TreeGrid 的架构



TreeGrid
维护一个数据模型,该模型管理
TreeGrid
用于通过 UI 呈现数据的原始数据。
TreeGrid
能够通过 dojo.data.api 提供的 API 访问数据存储以获取或处理数据,这是访问 Dojo 中的数据的标准方式。Dojo 提供许多以实现了 dojo.data.api 的 API 的数据存储,包括:
ItemFileReadStore
ItemFileWriteStore
(用户可以使用它们读取和处理 JSON 数据);用于其它数据格式的 XmlStore、CsvStore 和 OpmlStore;以及其他数据存储。表 1 列出了所有数据存储。

表 1. 实现的 Dojo 数据存储
数据存储作用
dojo.data.ItemFileReadStore 用于 JSON 数据的只读数据存储
dojo.data.ItemFileWriteStore 用于 JSON 数据的读/写数据存储
dojox.data.CsvStore 用于 CVS 数据的只读数据存储
dojox.data.OpmlStore 用于 Outline Processor Markup Language (OPML) 数据的只读数据存储
dojox.data.HtmlTableStore 用于 HTML 表数据的只读数据存储
dojox.data.XmlStore 用于 XML 数据的读/写数据存储
dojox.data.FlickrStore 用于 flickr.com 查询数据的只读数据存储。web 服务数据存储的杰出例子。
dojox.data.FlickrRestStore dojox.data.FlickrStore 的高级版本
dojox.data.QueryReadStore 用于来自服务器端的 JSON 数据的只读数据存储
dojox.data.AtomReadStore 用于 Atom XML 数据的只读数据存储
这是关于获取数据和正确地向用户呈现应用程序数据的视图。您可以通过定义
structure
参数定制
TreeGrid
的视图。有两种不同的
TreeGrid
视图。列式
TreeGrid
的布局更像典型的树风格,如图 3 所示。该视图在为
TreeGrid
指定
TreeModel
时创建。

图 3. 列式 TreeGrid



另一种
TreeGrid
视图是嵌套的
TreeGrid
,它由嵌套的
structure
定义,如下所示。

图 4. 嵌套的 TreeGrid



控制器响应并处理事件。
TreeGrid
继承自 dojo.grid.DataGrid,因此所有事件处理程序都与这里应用的 DataGrid 相关。您还可以通过将函数绑定到网格事件来定制事件处理程序,从而更加高效地控制数据和行为。

用法

可以在 HTML 中以声明的方式或以编程的方式定义
TreeGrid
TreeGrid
的大部分属性都是可选的,但
structure
store
(或
treeModel
,如果您需要创建列式
TreeGrid
)除外。
Structure
是定义
TreeGrid
视图布局的 JSON 对象。如果在 HTML 中以声明的方式定义了
TreeGrid
,该对象还可以通过标记表示出来。
store
的值应该是 JavaScript 变量的名称,而该变量包含用于为
TreeGrid
获取数据的储存对象。清单 1 显示了以声明的方式定义的
TreeGrid
的定义。

清单 1. 样例 TreeGrid 定义
<table dojoType="dojox.grid.TreeGrid" store="storeId">   <thead>     <tr>       <th field="field1" width="200px">Field 1</th>       <th field="childAttr">         <table>           <thead>             <tr>               <th field="cField1" width="200px">Child Field 1</th>               <th field="cField2" width="200px">Child Field 2</th>             </tr>           </thead>         </table>       </th>     </tr>   </thead> </table>
回页首

构建 Process Server 代理

WebSphere Process Server 提供各种编程接口来管理流程,比如 EJB、Web Service、JMS 和 REST。不过,只有 EJB API 提供完整的函数集。要利用 EJB API 的威力,您需要构建一个将
TreeGrid
连接到 Process Server 的代理。

创建样例流程应用程序

第一步是创建名为 SimpleSolution 的集成解决方案,它仅包含一个模块。为了让样例保持简单,我们构建只有一个接收/回复和一个人工任务的流程。人工任务只负责输入一个任意值作为回复操作的返回值。图 5 显示了该流程的定义。记住,您可以通过下面的 下载列表 下载本文使用的样例代码。

图 5. 流程定义



使用 Process Server API 管理流程

首先假设您使用的 IDE 为 WebSphere Integration Developer,以及代理应用程序运行在 Process Server 上(否则,您需要将 Process Server 客户端安装在您的服务器上)。这个例子首先创建一个动态 web 项目。您将看到会自动地引用所需的 Process Server 库。

图 6. SimpleBridge 动态 web 项目



Process Server 提供丰富的 API 来处理流程。您需要找到 EJB 服务的位置才能够访问这些 API。清单 2 显示了如何访问业务流程管理器服务。

清单 2. 访问业务流程管理器服务
// Obtain the default initial JNDI context InitialContext initialContext = new InitialContext(); // Lookup the remote home interface of the BusinessFlowManager bean Object result = initialContext.lookup("com/ibm/bpe/api/BusinessFlowManagerHome"); // Convert the lookup result to the proper type BusinessFlowManagerHome processHome =    (BusinessFlowManagerHome) javax.rmi.PortableRemoteObject.narrow(result,        BusinessFlowManagerHome.class); BusinessFlowManager processManager = processHome.create();
在获得了
BusinessWorkflowManager
的实例之后,就可以创建、处理和完成流程了。您可以使用清单 3 中的代码来访问流程模板。

清单 3. 访问流程模板
ProcessTemplateData[] processTemplates =    processManager.queryProcessTemplates(null, null, 0, null); for(int i = 0; i < processTemplates.length; i++){   //Do something to the process template }
使用清单 4 中的代码创建一个带有流程模板的流程实例,并为初始输入参数指定一个值。

清单 4. 创建流程实例
ProcessTemplateData template = processManager.getProcessTemplate(templateName); if(template != null){   // create a message for the single starting receive activity   ClientObjectWrapper input = processManager.createMessage(template.getID(),      template.getInputMessageTypeName());   DataObject myMessage = null;   if (input.getObject() != null && input.getObject() instanceof DataObject) {     myMessage = (DataObject) input.getObject();     // set the strings in the message, for example, a parameter named “input”     myMessage.setString("input", initialString);   }   // start the process   PIID piid = processManager.initiate(template.getName(), instanceName, input); }
完成以上步骤之后,转到 http://localhost:9080/bpc 并单击 Started By Me。这时可以看到刚才创建的实例,如下所示。

图 7. 样例流程实例



转到 My To-dos 可以看到一个需要处理的人工任务,如图 8 所示。这是在流程定义中定义的人工任务。

图 8. 需要处理的人工任务



要处理人工任务,您必须先找到它。可以使用流程管理器的
query
方法来获取所需的任务,如清单 5 所示。

清单 5. 获取 To-do 任务
QueryResultSet result = processManager.query(     "ACTIVITY.AIID, TASK.NAME",      "ACTIVITY.STATE = ACTIVITY.STATE.STATE_READY AND " +     "ACTIVITY.KIND = ACTIVITY.KIND.KIND_STAFF AND " +     "WORK_ITEM.REASON = WORK_ITEM.REASON.REASON_POTENTIAL_OWNER AND " +     "PROCESS_INSTANCE.NAME = '" + entity.getAttributeValue("NAME") + "'",     (String)null, (Integer)null, (TimeZone)null);  for(int k = 0; k < result.size(); k++){   // Get the AIID and the name of the task   result.next();   out.print("{id:'" + result.getOID(1) + "',");   out.print("label:'" + result.getString(2) + "'}"); }
要处理该任务,必须先声明它。只有通过声明它才能获取输入参数的值并完成任务。清单 6 显示了如何声明任务并获取输入参数的值。

清单 6. 声明任务并获取输入参数的值
ClientObjectWrapper input = processManager.claim(aiid); DataObject activityInput = null; if (input.getObject() != null && input.getObject() instanceof DataObject) {   activityInput = (DataObject) input.getObject();   String inputStr = activityInput.getString("input"); } processManager.cancelClaim(aiid);
至此,您可以处理任务并完成它了。清单 7 显示了一个例子。

清单 7. 处理任务
ActivityInstanceData activity = processManager.getActivityInstance(aiid); ClientObjectWrapper output = processManager.createMessage(aiid,    activity.getOutputMessageTypeName()); DataObject myMessage = null ; if(output.getObject() != null && output.getObject() instanceof DataObject) {   myMessage = (DataObject) output.getObject();   // set the parts in your message, for example, an order number   myMessage.setString("output", msg); } //complete the activity processManager.complete(aiid, output); Define the data exchange format
JSON 无疑是最佳的数据转换格式。您需要以 JSON 对象树的方式返回数据,这样
TreeGrid
才能够接收它。这种数据的结构非常直观。
Template
是与模板相关联的流程实例的父节点;to-do 任务是流程实例的子节点。

清单 8. 数据格式
{   identifier: "id",   label: "label",   items: [{     id: "1",     label: "Template 1",     instances: [{       id: "2",       label: "Instance 1",       tasks: [{         id: "3",         label: "ToDo 1",       },       {         id: "4",         label: "ToDo 2",       }]     }]   } }
回页首

使用 Dojo TreeGrid 管理流程

在设置好 WebSphere Process Server 之后,可以创建一个
TreeGrid
来接收和呈现 Process Server 提供的流程数据。可以为
TreeGrid
添加一些控件来管理这些流程。

连接到流程代理

如前所述,<table> 标记中的
store
属性(参见 清单 1)表明您希望使用哪个 DataStore 来获取数据。由于需要连接到流程代理,我们通过一个例子来解释如何进行连接。
JsonRestStore
是一个 Dojo 数据存储接口,它连接到支持以 GET、PUT、POST 和 DELETE 方式进行读写的 JSON HTTP/REST web 储存服务。还可以在用 HTML 标记定义
JsonRestStore
,如清单 9 所示。

清单 9. JsonRestStore 声明
<span dojoType="dojox.data.JsonRestStore"     jsId="jsonStore" target="SimpleSolution/ShowAll/"> </span>
target
属性表明服务器端数据源的目标 URL。它假设用户在相同的域中,因此
target
的值应该是一个相对路径。
jsId
是该储存仓库的标识符。

创建 TreeGrid

在这个例子中,在 HTML 中使用 <table> 标记以声明的方式定义
TreeGrid
。嵌套的 <th> 标记定义表中的列。清单 10 显示
TreeGrid
的声明。该结构对于上面的数据格式。

清单 10. TreeGrid 声明
<table dojoType="dojox.grid.TreeGrid" class="grid" autoHeight="true" jsId="grid"     store="jsonStore" rowSelector="true" defaultOpen=true>   <thead>     <tr>       <th field="label" width="20em" formatter="processSummary">Process Template</th>       <th field="instances" aggregate="sum">         <table>           <thead>             <tr>               <th field="label" width="20em" formatter="instanceSummary">Instance</th>               <th field="tasks" aggregate="sum">                 <table>                   <thead>                     <tr>                       <th field="label" width="25em" formatter="taskSummary">Tasks</th>                       <th field="status" width="20em">Status</th>                     </tr>                   </thead>                 </table>                </th>              </tr>            </thead>          </table>       </tr>   </thead> </table>
至此,您得到了一个
TreeGrid
,如下所示。

图 9. 显示流程数据的 TreeGrid



这个 TreeGrid 非常简单,但我们只完成了一半工作。下一步是给
TreeGrid
添加一些控件,使其能够与 WebSphere Process Server 通信以及处理流程。

与 WebSphere Process Server 通信

这个小节将给
TreeGrid
添加一些控件。从 Dojo 1.4 开始可以通过格式化程序(在网格单元格中显示返回值的 JavaScript 函数)将小部件添加到网格单元格。格式化程序还可以帮助格式化
TreeGrid
中的汇总单元格。

将通过格式化程序将两种类型的小部件添加到
TreeGrid
,如清单 11 所示:

dijit.form.ComboBox,用于改变任务状态
dijit.form.Button,用于提交请求

清单 11. 控制器格式化程序
// create an object to save all these ComboBox var comboObj = {}; var fmtStatus = function(value, idx, treepath){   // summary:   //    format the cell to a comboBox Widget   // value: string   //    the attribute value of this cell   // idx: integer   //    row index, it would be negative if the cell is header cell or summary cell   if(idx >= 0) {     // get the identifier     var id = jsonStore.getIdentity(grid.getItem(treepath));     comboObj[id] = new dijit.form.ComboBox({       store: comboStore,        searchAttr:"status"     });     comboObj[id].setValue(value);     return comboObj[id];   }else{     // for summary cell     return "";   } } 		 var fmtSubmit = function(value, idx){   if(idx >= 0){     return new dijit.form.Button({       label: "submit",        onClick: dojo.hitch(null, "submit", value)});   }else{     return "";   } }
您需要将格式化程序添加到
TreeGrid
的列,如下所示。

清单 12. 将格式化程序添加到列
<th field="status" width="20em" formatter=” fmtStatus”>Status</th> <th field="id" width="20em" formatter=” fmtSubmit”>Action</th>
现在,
TreeGrid
应该类似于图 10。

图 10. 带控制器的 TreeGrid



可以引入 Dojo Ajax IO 函数 dojo.xhr* 来与 WebSphere Process Server 进行通信。单击 Submit 将向服务器发送 XHR 请求以提交新的状态。在收到服务器的响应之后,网格将进行刷新以正确地反映流程,如清单 13 所示。

清单 13. 与 WebSphere Process Server 通信
var submit = function(id){	   var status = comboObj[id].getValue();     dojo.xhrPost({       url: "SimpleSolution/" + status + "/" + id,       load: function(data){         if(data === "successful"){           grid.update();         }else{           console.warn("operation failed:", data);         }       },       error: function(error){         console.err(error);       }   }); }
现在,每次单击 Submit 都会向 WebSphere Process Server 发送一个 XHR 请求。您将能够通过服务响应知道操作是否成功。

回页首

结束语

在本文中,您学习了如何使用 Dojo
TreeGrid
处理 WebSphere Process Server 的流程。
TreeGrid
本质上能够处理分层数据结构。您可以根据特定的应用程序需求定制
TreeGrid
,从而得到便于操作数据的 Web 2.0 风格的 UI。

回页首

下载

描述名字大小下载方法
本文样例代码code.zip26KBHTTP
关于下载方法的信息

参考资料

学习

访问所有官方 Dojo 文档,包括入门信息、参考指南和开发人员笔记。

全面了解 Dojo toolkit 并获取 工具箱文档

阅读关于 Dojo 的 分层数据和通过 dojo.data 进行访问

developerWorks 中国网站 WebSphere 产品专区 提供关于 WebSphere 软件平台的技术资源。

developerWorks Web development 专区:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。

developerWorks Ajax 资源中心:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。

developerWorks Web 2.0 资源中心,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过 Web 2.0 新手入门 栏目,迅速了解 Web 2.0 的相关概念。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐