使用 DOJO 开发定制小部件,第 2 部分

使用通用的网格处理程序生成 DOJO DataGrid 组件

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 使用 DOJO 开发定制小部件,第 2 部分

敬请期待该系列的后续内容。

此内容是该系列的一部分:使用 DOJO 开发定制小部件,第 2 部分

敬请期待该系列的后续内容。

简介

我们为本系列开发的定制小部件是基于 DOJO 1.2.3,并已经使用 Mozilla Firefox 3.0.11 在 WebSphere Integration Developer V6.2 上的 Business Space V6.2 中测试过。但是,我们开发的通用框架概念也适用于不使用 Business Space 的 DOJO 应用程序。学习本系列需要具备 DOJO 和 iWidget 框架的基本知识。

我们将讨论在基于 DOJO 的应用程序中经常遇到的主题。本系列分为以下几部分:

  • 第 1 部分:使用通用的 markup 处理程序生成 DOJO markup
  • 第 2 部分:使用通用的网格处理程序创建具有分页功能的 Dojo DataGrid 组件
  • 第 3 部分:在 iWidget 中使用多个模板和如何继承基本小部件
  • 第 4 部分:使用通用的 REST 处理程序从 iWidget 发出可配置的 REST 调用

在第 2 部分中,我们将演示如何使用通用网格处理程序通过编程方式生成一个具有分页功能的 Dojo DataGrid 组件。考虑到重用性和易维护性,我们提出一种灵活的设计方法,即在 JSON 文件中定义布局本身。

本文将向您完整演示使用 DojoGridHandler JavaScript 类生成 Dojo DataGrid 组件的必需步骤,并会告诉您网格处理程序是如何工作的。可供下载的 Dojo_sample.zip 中包含以下示例文件:

  • DojoGridHandler.js:通用网格处理程序 JavaScript 类。
  • gridHandlerLayout.json:包含 DataGrid 小部件的布局信息的 JSON 文件。
  • DojoItemFileWriteStore.js:覆盖 ItemFileWriteStore.js 的定制数据存储。
  • DojoPagingTable.js:处理分页功能的分页表 Javascript 类。
  • pagingTable.html:分页表小部件使用的 HTML 模板文件;它包含用于放置按钮的 div 标记,这些按钮可以导航至不同的页面。
  • gridView.html:包含 HTML markup 的 HTML 模板文件;它包含有应在其中放置网格和分页表的 div 标记。

定义网格布局

生成 Dojo DataGrid 的第一步是定义网格布局。布局信息包括想要放置在网格中的列,还有一些附加信息,如格式信息、列分组、列宽等等。

图 1 是 Business Space 示例屏幕,显示的是使用 DojoGridHandler 生成的 DataGrid。

图 1. 使用 DojoGridHandler 生成的 DataGrid
使用 DojoGridHandler 生成的 DataGrid
使用 DojoGridHandler 生成的 DataGrid

我们将演示如何编写生成上例布局信息的 JSON 文件,但我们将首先描述网格处理程序如何实际生成 Dojo DataGrid 小部件。

Dojo 网格处理程序工作原理

DojoGridHandler 类在 createGrid( ) 方法中加载包含布局信息的 JSON 文件,如清单 1 所示。

清单 1. createGrid( ) 方法
createGrid : function(thisVar,gridHeadersURL,gridComponentId,gridDisplayDivId,
				pagingDivId,onCellClickMethodName)
	{
		this.gridComponentId=thisVar.iContext.widgetId+gridComponentId;
		this.pagingDivId=thisVar.iContext.widgetId+pagingDivId;
		this.thisVar = thisVar;
		
		var req = {	url:gridHeadersURL,
				handleAs: "json",
				sync:true,
				load: dojo.hitch(this, function(data){ 
this._gridHeadersURLDef(data,gridDisplayDivId,onCellClickMethodName); }),
				error: dojo.hitch(this, this._gridHeadersURLDefError)
			  };

		 dojo.xhrGet(req);

	}

一旦成功加载 JSON 文件后,createGrid 方法就调用 _gridHeadersURLDef 方法。 _gridHeadersURLDef 方法从 JSON 文件中读取布局信息。它还会检查布局中的每一列是否有 formatter 属性。如果有,就将相应的 formatter 方法应用到正确的范围内。

然后,_gridHeadersURLDef() 方法将调用 drawDataGrid() 方法。

清单 2. _gridHeadersURLDef( ) 方法。

清单 2. _gridHeadersURLDef( ) 方法
_gridHeadersURLDef: function(response,gridDisplayDivId, onCellClickMethodName){
		this.gridSearchResultDef=eval(response).layout;
	
		for(var i=0; i<this.gridSearchResultDef.length;i++){
			
			rowheaders = this.gridSearchResultDef[i];
			for(var j=0; j<rowheaders.length;j++)
			{
				var callback=rowheaders[j].formatter;
				if(callback){
		rowheaders[j].formatter=dojo.hitch(this.thisVar,callback);
					console.debug(callback);
				}
				var 
    displayName=this.iwidget_messages[rowheaders[j].name];
				
				rowheaders[j].name=displayName;
			}
		}

		this._drawDataGrid(this.gridSearchResultDef, gridDisplayDivId, 
   onCellClickMethodName);

}

drawDataGrid 方法实例化 DataGrid 小部件并调用 DataGrid 的启动方法。清单 3 中的代码片段生成 DataGrid 小部件,并将 columnReordering clientSortautoHeight 设置为 true。网格数据来自于定制数据存储 DojoItemFileWriteStoreDojoItemFileWriteStore 存储覆盖了 ItemFileWriteStore 中的 _getItemsFromLoadedData() 方法,以读取显示分页信息所需的属性(totalRecordsstartRecordIndexendRecordIndex)。

覆盖 ItemFileWriteStore 的主要目的是为了得到总行数(我们想要在用户界面中显示总行数),因为 ItemFileStore 没有可以返回总行数的 API。

清单 3. _drawDataGrid( ) 方法
_drawDataGrid : function(resultDef,gridDisplayDivId,onCellClickMethodName){
			console.debug("begin startUpGrid searchResultDef."+resultDef);
			var pmi=new dojox.widget.PlaceholderMenuItem
				( {label : "GridColumns"});
			var gridMenu= new dijit.Menu({style : "display: none;"});
			gridMenu.addChild(pmi);

			this.dataStore = new com.ibm.bcgex.common.DojoItemFileWriteStore
({data:{items:[]}});
			this.gridWidget= new dojox.grid.DataGrid({
					id:this.gridComponentId,
		dojoAttachPoint:this.gridComponentId,
					store: this.dataStore,
					autoHeight:true,
					rowSelector: '20px',
					clientSort:true,
					style:"border: solid black 1px",
					structure: resultDef ,
					columnReordering: true,
					headerMenu: gridMenu}, 
dojo.byId(this.thisVar.iContext.widgetId+gridDisplayDivId));
	

this.gridWidget.startup();
dojo.connect(this.gridWidget
, "onCellClick", dojo.hitch(this.thisVar,onCellClickMethodName));
},

populateGrid() 方法将数据加载到 DataGrid 小部件中。该方法调用 REST API,然后调用 _loadRestGridData 方法。如清单 4 所示,该方法实际完成数据填充。

清单 4. _loadRestGridData() 方法
_loadRestGridData: function(data)

{

	this.data=eval(data);   
		
	this.dataStore = new com.ibm.bcgex.common.DojoItemFileWriteStore
		({ data: this.data});

	var grid = dijit.byId(this.gridComponentId);

	grid.setStore(this.dataStore);

	this.populatingPagingDiv(this.dataStore);   	

}

然后,_loadRestGridData() 方法调用 populatingPagingDiv() 方法,该方法被用来构造分页表。

populatingPagingDiv() 方法用于在网格中填充分页数据。它将调用 _drawPagingTable() 方法,如清单 5 所示,该方法用于构造分页表。为了使分页功能起作用,需要从 REST 调用中作为数据的一部分返回以下属性:

  • totalRecords
  • startRecordIndex
  • endRecordIndex
清单 5. _drawPagingTable () 方法
_drawPagingTable: function(totalRecords,startRecordIndex,endRecordIndex){

		console.debug("Inside drawPagingTable...");

		if(this.pagingTable==null)

		{
			this.pagingTable = new
com.ibm.bcgex.common.DojoPagingTablethis.thisVar.iContext,this.iwidget_messages,
this.gridComponentId);

			this.pagingTable.setPagingCallback
(this, "pagingTableActionPopulateGrid");

			dojo.byId(this.pagingDivId).appendChild
(this.pagingTable.domNode);

			this.pagingTable.insertLayoutDijits();
		}
                                            this.pagingTable.setRecordNbrNTotalCounts
(startRecordIndex,endRecordIndex,totalRecords);
}

如何在代码中使用网格处理程序

现在,让我们开始学习如何从代码中调用网格处理程序 JavaScript 类。

  1. 在 JSON 文件中定义布局属性。

    需要在 JSON 文件(如 gridHandlerLayout.json)中定义 DataGrid 的所有列的布局属性。以下的代码片段显示的是 gridHandlerLayout JSON 文件,其中包含了 图 1 所示的示例屏幕的 DataGrid 的布局信息。

    ({
    	"layout" : [[
    		{
    		    "field" : "name",
    		    "name": "Name",
    		    "formatter" : "formatName" 
    		},
    		{
    		    "field" : "gender",
    		    "name": "Gender"
    		},
    		{
    		    "field" : "fullName",
    		    "name": "Full Name",
    		    "formatter" : "formatFullName" 
    		  
    		},
    		{
    		    "field" : "department",
    		    "name": "Department"
    		},
    		{
    		    "field" : "location",
    		    "name": "Location"
    		},
    		{
    		    "field" : "delete",
    		    "name": "Delete",
    		    "formatter" : "formatDelete" 
    		}
    	    ]]
    })
  2. 下一步,实例化 DojoGridHandler JavaScript 类,如下所示:

    this.gridHandler = new com.ibm.bcgex.common.DojoGridHandler(this.iContext,this.rootContext);
  3. 定义一个变量,指向包含布局信息的 JSON 文件,如下所示:

    var configURL = this.iContext.io.rewriteURI(""+"gridHandlerLayout.json");
  4. 按如下方式调用 createGrid 方法:
    this. gridHandler.createGrid(this, configURL, " employeeGrid "," employeeGridDiv ",
    	" employeeGridPagingDiv ","gridOnCellClick");
  5. 在 HTML 模板文件中,必须含有两个 div 标记,包含 ID employeeGridDivemployeeGridPagingDiv(参见 下载 中提供的 gridview.html)。
  6. 为了在网格中填充数据,需要调用 populateGrid 方法,如下所示:
    this. gridHandler.populateGrid();
  7. 要格式化 DataGrid 中的列(例如,您想要某些字段显示为图片链接),需要在布局中定义 formatter 属性。因此,formatDelete() 方法看上去如下所示:
    formatDelete : function(value){
    		
    var imagePath=this.getImageRootContext(); // give the image path here
    return "<img src=\""+imagePath+"redx.gif\"\"/>";
    		
    }

结束语

您已学习了如何使用 DojoGridHandler 通过编程的方式创建 Dojo DataGrid 小部件。您可以使用网格处理程序以最少量的代码在 Business Space 中创建具有分页功能的 DataGrid 组件。您可以在不影响代码的情况下轻松改变布局。


下载资源


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=489632
ArticleTitle=使用 DOJO 开发定制小部件,第 2 部分: 使用通用的网格处理程序生成 DOJO DataGrid 组件
publish-date=05132010