电竞比分网-中国电竞赛事及体育赛事平台

分享

使用 MVC 設(shè)計(jì)模式的 Dojo Grid

 LibraryPKU 2013-11-12

簡(jiǎn)介

Dojo 是一個(gè)可移植的開源 JavaScript 工具包,使用它可以快速構(gòu)建富客戶端 Web 應(yīng)用程序。它包含的豐富的實(shí)用程序可用于構(gòu)建快速響應(yīng)的應(yīng)用程序。而且,它還提供了許多預(yù)先封裝的開箱即用小部件,您可以通過(guò)這些小部件立即開始使用 Dojo。但是,Dojo 沒有提供文檔來(lái)詳細(xì)演示如何使用每種小部件,比如 Dojo Grid。Dojo Grid 在某種程度上就像一種可以在網(wǎng)頁(yè)上呈現(xiàn)的微型電子表格。本文將從模型-視圖-控制器(MVC)設(shè)計(jì)模式的角度指導(dǎo)您使用 Dojo Grid 的主要功能,幫助您輕松理解和掌握 Dojo Grid,即使您以前從未使用過(guò)它。

MVC 是軟件工程領(lǐng)域使用的一種架構(gòu)模式。模式的成功使用可以將業(yè)務(wù)邏輯問(wèn)題與用戶界面分離開來(lái),使開發(fā)人員能夠自由修改一種業(yè)務(wù)邏輯,而不會(huì)影響到其他邏輯。 這種模式的控制器通過(guò)用戶界面處理輸入事件,觸發(fā)在后臺(tái)的模型修改。模型操作應(yīng)用程序數(shù)據(jù),視圖使用模型來(lái)向用戶呈現(xiàn)結(jié)果。這種模式被廣泛應(yīng)用于許多框架 中,比如 Microsoft? MFC、Java? Swing、Java Enterprise Edition 等。下面各節(jié)將分別介紹按 MVC 劃分的表格特性。

模型

為了區(qū)分原始數(shù)據(jù)與 UI 的生動(dòng)外觀,Dojo Grid 維護(hù)著一個(gè)數(shù)據(jù)模型,用來(lái)存儲(chǔ)表格將會(huì)操作的所有原始數(shù)據(jù)。例如,日期/時(shí)間類型數(shù)據(jù)通常以毫秒為單位進(jìn)行存儲(chǔ),而不是存儲(chǔ)為 “2009-7-22” 等人類可讀的格式,所以可以更加輕松地構(gòu)造并將它轉(zhuǎn)換為其他類型的日期對(duì)象。

與所有 MVC 小部件一樣,表格具有自己的數(shù)據(jù)模型,稱為數(shù)據(jù)存儲(chǔ)。在 Dojo 中,幾乎所有需要使用數(shù)據(jù)存儲(chǔ)的小部件都能夠使用 ItemFileReadStoreItemFileWriteStore 等函數(shù)訪問(wèn)通用數(shù)據(jù)存儲(chǔ),無(wú)需使用特定于它們的數(shù)據(jù)的新 API。

ItemFileReadStore 用于讀取特定格式的 JSON 數(shù)據(jù)。DojoX 項(xiàng)目還提供了 XmlStore、CsvStoreOpmlStore 等更多存儲(chǔ)方式。這些存儲(chǔ)方式用于處理可以相應(yīng)格式輸出數(shù)據(jù)的服務(wù)器。

在 Dojo Grid 和許多其他 MVC 小部件中,所有數(shù)據(jù)通常都以項(xiàng)或項(xiàng)的屬性的形式在數(shù)據(jù)存儲(chǔ)中操作。通過(guò)這種方式,可以采用一種標(biāo)準(zhǔn)方式訪問(wèn)數(shù)據(jù),許多小部件可同時(shí)使用數(shù)據(jù)。清單 1 給出了本文中使用的示例數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)。


清單 1. 簡(jiǎn)單數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)示例
				
{
    identifier: 'id',
    label:'name',
    items: [
{id:0, name: 'Alex', manager: true, sex: 'Male', age:30, date: 1097990400000, 
annualLeaveTotal: 15, annualLeaveTaken:2},
{id:1, name: 'Jack', manager: false, sex: 'Male', age:26, date: 1184995200000,
annualLeaveTotal: 10, annualLeaveTaken:3},
{id:2, name: 'Rose', manager: true, sex: 'Female', age:40, date: 894604800000, 
annualLeaveTotal: 20, annualLeaveTaken:4},
{id:3, name: 'Wang', manager: true, sex: 'Male', age:44, date: 836630400000, 
annualLeaveTotal: 20, annualLeaveTaken:5},
…..
}            

在本示例中:

  • 每項(xiàng)都有 8 個(gè)屬性。
  • id 屬性是一個(gè)唯一標(biāo)識(shí)符。

數(shù)據(jù)存儲(chǔ)可以采用兩種方式構(gòu)建:聲明為標(biāo)記或以編程方式構(gòu)造。

使用標(biāo)記構(gòu)建數(shù)據(jù)存儲(chǔ)

要使用標(biāo)記構(gòu)建數(shù)據(jù)存儲(chǔ),首先需要用于有序存儲(chǔ)所有數(shù)據(jù)的 JSON 文件(參見清單 2)。本文使用的是 data.json 文件。,然后可以在 HTML 文件中編寫清單 2 中的標(biāo)記。


清單 2. 在 HTML 中聲明數(shù)據(jù)存儲(chǔ)
				
<span dojoType="dojo.data.ItemFileWriteStore" jsId="myStore"
      url="data.json"></span>            

接下來(lái),將存儲(chǔ)分配給表格,如清單 3 所示。


清單 3. 分配表格數(shù)據(jù)存儲(chǔ)
				
<table id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" store="myStore"
 rowSelector="10px">
	<thead>
  		 ...
	<thead>
<table>            

現(xiàn)在,當(dāng) Dojo 解析 HTML 代碼并構(gòu)造此表格時(shí),它創(chuàng)建一個(gè) Dojo 存儲(chǔ)對(duì)象,該對(duì)象將從 data.json 文件獲取數(shù)據(jù),然后將表格存儲(chǔ)設(shè)置為 “myStore”。圖 1 顯示了生成的表格的一個(gè)示例。


圖 1. 構(gòu)造得到的簡(jiǎn)單表格
此數(shù)據(jù)表格顯示了一個(gè)員工信息表,在每行上包含每個(gè)員工的數(shù)據(jù),就像電子表格一樣

使用標(biāo)記構(gòu)建表格存儲(chǔ)非常簡(jiǎn)單快捷。但是,如果數(shù)據(jù)來(lái)自一臺(tái)服務(wù)器并且以動(dòng)態(tài)形式組織,那么您需要以編程方式構(gòu)建表格和它的存儲(chǔ)。

以編程方式構(gòu)建數(shù)據(jù)存儲(chǔ)

要?jiǎng)討B(tài)地構(gòu)造和更改表格的存儲(chǔ),同時(shí)對(duì)服務(wù)器端做出響應(yīng),您必須:

  • 使用 JavaScript 以編程方式將傳入的數(shù)據(jù)重新組織為 Dojo 熟悉的數(shù)據(jù)。
  • 創(chuàng)建一個(gè) Dojo 存儲(chǔ)。
  • 將存儲(chǔ)設(shè)置為表格。

清單 4 中的代碼將一個(gè) JSON 對(duì)象構(gòu)造為數(shù)據(jù)存儲(chǔ)格式。


清單 4. 重新組織數(shù)據(jù)
				
generateStoreData: function(/*JSON array*/itemList){
var data = {};
var items = [];
for (var i = 0; i < itemList.length; i++) {
	var item = {};
	item["id"]     = itemList[i].id;
	item["name"]   = itemList[i].name;
	item["manger"] = itemList[i].isManger;
	item["sex"]    = itemList[i].sex;
	item["age"]    = itemList[i].age;
	item["date"]   = itemList[i].date;
	item["annualLeaveTotal"] = itemList[i].altotal;
	item["annualLeaveTaken"] = itemList[i].altaken;
	items.push(item);
       }
data["identifier"] = "id";
data["label"] = "name";
data["items"] = items;
return data;    
}            

接下來(lái),可以創(chuàng)建一個(gè)存儲(chǔ)并將其設(shè)置為表格。


清單 5. 創(chuàng)建并設(shè)置表格存儲(chǔ)
				
   dijit.byId("grid").store = new dojo.data.ItemFileReadStore({
                  data: this.generateStoreData(itemList)
     });            

所有這些步驟所得到的表格與 圖 1 所示完全一樣。

查詢數(shù)據(jù)存儲(chǔ)

Dojo Grid 通常在其數(shù)據(jù)模型中存儲(chǔ)整個(gè)數(shù)據(jù)源。但是,隨著數(shù)據(jù)大小的不斷增長(zhǎng),這可能影響到性能。實(shí)際上,當(dāng) Dojo Grid 存儲(chǔ)中的項(xiàng)超出了一定數(shù)量時(shí),并且如果每項(xiàng)都具有許多屬性,排序、搜索和呈現(xiàn)等表格操作的性能就會(huì)顯著下降。

但是,可以通過(guò)一些方式來(lái)改善性能??梢跃帉懘a來(lái)讓服務(wù)器向?yàn)g覽器發(fā)送有限的數(shù)據(jù),并將這些數(shù)據(jù)構(gòu)造到一個(gè)表格數(shù)據(jù)存儲(chǔ)中,或者可以使用或擴(kuò)展 Dojox 項(xiàng)目提供的 QueryReadStore 來(lái)從服務(wù)器動(dòng)態(tài)加載數(shù)據(jù)。這種方法可用于從服務(wù)器上大型的數(shù)據(jù)存儲(chǔ)中檢索數(shù)據(jù)塊。


清單 6. 使用查詢存儲(chǔ)來(lái)處理大型數(shù)據(jù)
				
<div dojoType="dojox.data.QueryReadStore" jsId="store" url="../someServlet"
 requestMethod="post"></div>
	
<div dojoType="dojox.grid.data.DojoData" jsId="model" store="store"
 sortFields="[{attribute: 'name', descending: true}]" rowsPerPage="30"> </div>
		
<div id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" model="model" structure="layout"
 rowSelector="10px"><div>            

DojoX 項(xiàng)目提供了許多其他數(shù)據(jù)存儲(chǔ)來(lái)滿足不同的用途。表 1 給出了 Dojo 中目前可用的存儲(chǔ)以及它們的目標(biāo)。


表 1. Dojo 中的可用存儲(chǔ)
Dojo 存儲(chǔ) 用途
dojo.data.ItemFileReadStore 用于 JSON 數(shù)據(jù)的只讀存儲(chǔ)。
dojo.data.ItemFileWriteStore 用于 JSON 數(shù)據(jù)的讀/寫存儲(chǔ)。
dojox.data.CsvStore 用于逗號(hào)分隔變量 (CSV) 格式數(shù)據(jù)的只讀存儲(chǔ)。
dojox.data.OpmlStore 用于大綱處理標(biāo)記語(yǔ)言(Outline Processor Markup Language,OPML)的只讀存儲(chǔ)。
dojox.data.HtmlTableStore 用于 HTML 格式表格中所保存數(shù)據(jù)的只讀存儲(chǔ)
dojox.data.XmlStore 用于基本 XML 數(shù)據(jù)的讀/寫存儲(chǔ)。
dojox.data.FlickrStore 針對(duì) flickr.com 上的查詢的讀取存儲(chǔ),是 Web 服務(wù)數(shù)據(jù)存儲(chǔ)的一個(gè)出色示例。
dojox.data.FlickrRestStore 針對(duì) flickr.com 上的查詢的讀取存儲(chǔ),是 Web 服務(wù)數(shù)據(jù)存儲(chǔ)的一個(gè)出色示例。這是 FlickrStore 的一個(gè)更高級(jí)的版本。
dojox.data.QueryReadStore 類似于 ItemFileReadStore,是用于 JSON 數(shù)據(jù)的只讀存儲(chǔ),但會(huì)在收到每個(gè)請(qǐng)求時(shí)查詢服務(wù)器。
dojox.data.AtomReadStore 用于 Atom XML 文檔的讀取存儲(chǔ)。

自定義 Dojo 數(shù)據(jù)存儲(chǔ)

您也可以使用 Dojo.data API 編寫自定義數(shù)據(jù)存儲(chǔ),數(shù)據(jù)訪問(wèn)應(yīng)該劃分為幾個(gè)部分,而且數(shù)據(jù)存儲(chǔ)應(yīng)該使用合適的 API 實(shí)現(xiàn)每一部分。

  • dojo.data.api.Read 支持讀取數(shù)據(jù)項(xiàng)和這些數(shù)據(jù)項(xiàng)的屬性。這也包括搜索、排序和過(guò)濾數(shù)據(jù)項(xiàng)。
  • dojo.data.api.Write 支持創(chuàng)建、刪除和更新數(shù)據(jù)項(xiàng)和這些數(shù)據(jù)項(xiàng)的屬性。不是所有的后端服務(wù)都支持修改數(shù)據(jù)項(xiàng)。實(shí)際上,大部分公共服務(wù),比如 Flikr、Delicious 和 GoogleMaps,都主要是基于讀取的數(shù)據(jù)提供程序。
  • dojo.data.api.Identity 支持基于項(xiàng)目的唯一標(biāo)識(shí)符(如果它有)來(lái)定位和查找項(xiàng)目。不是所有的數(shù)據(jù)格式都具有可用于查找數(shù)據(jù)項(xiàng)的唯一標(biāo)識(shí)符。
  • dojo.data.api.Notification 支持通知監(jiān)聽程序發(fā)生在存儲(chǔ)中的數(shù)據(jù)項(xiàng)上的變更事件。一個(gè)項(xiàng)的基本變更事件包括創(chuàng)建、刪除和更新。這些變更對(duì)于會(huì)定期輪詢后端服務(wù)以進(jìn)行數(shù)據(jù)刷新的數(shù)據(jù)存儲(chǔ)尤其有用。

視圖

在 MVC 設(shè)計(jì)模式中,視圖從模型檢索應(yīng)用程序數(shù)據(jù)并將其呈現(xiàn)給用戶。表格提供了許多函數(shù)來(lái)簡(jiǎn)化對(duì)呈現(xiàn)的更改。在以下幾節(jié)中,我將展示一些典型用法,從視圖角度演示強(qiáng)大的表格功能。.

使用標(biāo)記進(jìn)行表格布局定義

總體而言,表格可以在 HTML 標(biāo)記中以聲明方式定義,也可以在 JavaScript 中以編程方式定義。清單 7 給出了一個(gè)使用標(biāo)記的高級(jí)結(jié)構(gòu)定義,它會(huì)生成如圖 2 所示的顯示外觀。


清單 7. 使用標(biāo)記定義布局的 JavaScript 代碼
				
<table id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" store="myStore" 
     rowSelector="10px">
<thead>
	<tr>                				
		<th field="id" width="10px">ID</th>
		<th field="name">Name</th>
		<th field="manager" with="50px">Is manager</th>	
		<th field="sex" width="50px">Sex</th>
		<th field="age" width="50px">Age</th>
		<th field="date" width="100px">On Board date</th>
	</tr>
	<tr>
		<th field="annualLeaveTotal" colspan="3">
                        		Total annual leave days
               	</th>
		<th field="annualLeaveTaken" colspan="3">
			Annual leave days already taken 
	             </th>
	</tr>
</thead>
</table>            


圖 2. 使用標(biāo)記定義布局的表格
這個(gè)電子表格樣式的表格在頂部顯示了一組標(biāo)簽,在底部顯示了各個(gè)員工的數(shù)據(jù)

以編程方式定義表格布局

表的結(jié)構(gòu)也可以以編程方式設(shè)置。structure 屬性可以指定一個(gè)對(duì)象來(lái)定義單元格結(jié)構(gòu)。


清單 8. 以編程方式定義布局的 JavaScript 代碼
				
var layout = [{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
	 name: 'Is manager',
	 field:'manager',
	width:'100px'
	}, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            },{
                name: 'On Board date',
                field: 'date',
                width: '100px'
            }, {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                width: '100px'
            }, {
                name: 'Annual leave days already taken',
               	field: 'annualLeaveTaken',
                width: '100px'
	}];

var grid = new dojox.grid.DataGrid({
            id: 'grid',
            store: myStore,
            structure: layout
        }, dojo.byId('grid'));            

鎖定列,禁用橫向滾動(dòng)

可以鎖定 一組列,阻止它們橫向滾動(dòng),而允許其他列繼續(xù)滾動(dòng)。要實(shí)現(xiàn)此功能,您可以使用兩種結(jié)構(gòu)并將一種結(jié)構(gòu)的 noscroll 屬性設(shè)置為 true。

在清單 9 所示的示例中,聲明了兩種結(jié)構(gòu)。針對(duì) ID 和 Name 列的結(jié)構(gòu)的 noscroll 屬性設(shè)置為 true。然后使用一個(gè)數(shù)組將這兩種結(jié)構(gòu)組合到一個(gè)布局結(jié)構(gòu)中。


清單 9 .鎖定 ID 和 Name 列的 JavaScript 代碼
				
var fixlayout = {
                noscroll: true,
                cells: [{
                    name: 'ID',
                    field: 'id',
                    width: '10px'
		             
                }, {
                    name: 'Name',
                    field: 'name',
                    width: '50px'
                }]
            };

var mainlayout = {
                onBeforeRow: beforerow,
                onAfterRow: afterrow,
                cells: [{
                    name: 'Is manager',
                    field: 'manager',
                    width: '200px'
                }, {
                    name: 'Sex',
                    field: 'sex',
                    width: '50px'
                }, {
                    name: 'Age',
                    field: 'age',
                    width: '50px'
                }, {
                    name: 'On Board date',
                    field: 'date',
                    width: '100px',
                }, {
                    name: 'Total annual leave days',
                    field: 'annualLeaveTotal',
                    width: '100px'
                }, {
                    name: 'Annual leave days already taken',
                    field: 'annualLeaveTaken',
                    width: '100px'
                }]
            };

var layout = [fixlayout, mainlayout];            

從圖 3 可以看出 ID 和 Name 列已被鎖定,但剩余的列仍然可以橫向滾動(dòng)。


圖 3. 具有固定列的表格
這個(gè)表格中數(shù)據(jù)與圖 2 中的表格相同,但現(xiàn)在橫向滾動(dòng)條僅適用于 ID 和 Name 右側(cè)的列

包含多行數(shù)據(jù)的行

表格支持單個(gè)邏輯行包含多行數(shù)據(jù)。這可以通過(guò)將 colSpan 屬性添加到布局定義中來(lái)實(shí)現(xiàn),如清單 10 所示。


清單 10. 定義包含多行數(shù)據(jù)的行的 JavaScript 代碼
				
var layout = [[{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
	  name: 'Is manager',
	  field:'manager',
	  width:'100px'
 }, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            },{
                name: 'On Board date',
                field: 'date',
                width: '100px'
            }], [ {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                colSpan: '2'
            }, {
                name: 'Annual leave days already taken',
               	field: 'annualLeaveTaken',
                colSpan: '2'
            }]];            

名為 “Total annual leave days” 和 “Annual leave days already taken” 的列與其他列的數(shù)據(jù)位于同一行


圖 4. 具有多行的表格
同樣是相同的表格,但現(xiàn)在 Total annual leave days 列擴(kuò)展到了 ID 和 Name 列之下,Annual leave days already taken 擴(kuò)展到了 Is Manager 和 Sex 列之下

表格數(shù)據(jù)格式

可以使用一種表格格式函數(shù)來(lái)更改數(shù)據(jù)存儲(chǔ)中的數(shù)據(jù)的呈現(xiàn)方式。這是 MVC 的一種核心概念。它可以定義一種符合用戶當(dāng)?shù)亓?xí)慣的數(shù)據(jù)格式,比如日期,甚至可以構(gòu)造 HTML 組件,比如復(fù)選框。清單 11 給出了一個(gè)示例。


清單 11. 格式化表格數(shù)據(jù)的 JavaScript 代碼
				
var dateFormatter = function(data, rowIndex){
                return dojo.date.locale.format(new Date(data), {
                    datePattern: "dd MMM yyyy",
                    selector: "date",
                    locale: "en"
                });
            };

var managerFormatter = function(data, rowIndex){
                if (data) {
                    return "<input type='checkbox' checked />";
                }
                else {
                    return "<input type='checkbox'  />";
                    
                }
            };

var layout = [{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
                name: 'Is manager',
                field: 'manager',
                formatter: managerFormatter,
                width: '100px'
            }, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            }, {
                name: 'On Board date',
                field: 'date',
                width: '100px',
                formatter: dateFormatter
            }, {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                width: '100px'
            }, {
                name: 'Annual leave days already taken',
                field: 'annualLeaveTaken',
                width: '100px'
            }];            


圖 5. 表格數(shù)據(jù)格式
此表格要求 On Board Date 列的格式為 DD-MMM-YYYY,Is manager 顯示復(fù)選框,而不是 true/false

使用 get interface

您可以使用 get interface 在數(shù)據(jù)存儲(chǔ)之外定義其他列來(lái)動(dòng)態(tài)檢索值。在上面的例子中,我擁有 “Total annual leave days” 和 “Annual leave days already taken” 列。如果您想知道還有多少天年假(可以根據(jù)現(xiàn)有的兩列計(jì)算得出),可以使用 get interface 動(dòng)態(tài)檢索它。

我添加了一個(gè)名為 “Annual leave days left” 的新列,它的值為 “Total annual leave days” 減 “Annual leave days already taken” 的差,如清單 12 所示。


清單 12. 使用 get interface 的 JavaScript 代碼
				
function getLeftDays(rowIndex, item){
                if (item != null) {
                    return item.annualLeaveTotal - item.annualLeaveTaken;
                }
            }


var layout = [{
                name: 'ID',
                field: 'id',
                width: '10px'
            }, {
                name: 'Name',
                field: 'name',
                width: '50px'
            }, {
                name: 'Is manager',
                field: 'manager',
                formatter: managerFormatter,
                width: '100px'
            }, {
                name: 'Sex',
                field: 'sex',
                width: '50px'
            }, {
                name: 'Age',
                field: 'age',
                width: '50px'
            }, {
                name: 'On Board date',
                field: 'date',
                width: '100px',
                formatter: dateFormatter
            }, {
                name: 'Total annual leave days',
                field: 'annualLeaveTotal',
                width: '100px'
            }, {
                name: 'Annual leave days already taken',
                field: 'annualLeaveTaken',
                width: '100px'
            }, {
                name: 'Annual leave days left',
                get: getLeftDays,
                width: '100px'
            }];            


圖 6. 使用 get interface
此表格具有一個(gè)新列 “Annual leave days left”,它的值為 “Total annual leave days” 減 “Annual leave days already taken” 的差

控制器

在 MVC 設(shè)計(jì)模式中,控制器處理和響應(yīng)事件(通常為用戶操作),并且可以間接調(diào)用模型上的變更。Dojo Grid 中的控制器具有非常強(qiáng)大的功能,它提供了許多方法來(lái)自定義表格行為,例如如何處理事件、如何排序數(shù)據(jù)、如何過(guò)濾數(shù)據(jù)等。

在以下各節(jié)中,我將展示如何在 Dojo Grid 中使用和自定義控制器。

事件處理

Dojo Grid 具有一種強(qiáng)大的事件處理機(jī)制,它根據(jù)不同的表格元素和事件類型來(lái)提供事件調(diào)用接口。例如,它可以在一行或單元格上響應(yīng) click 事件,它也可以響應(yīng) mouseover 事件。所以,在自定義這些事件處理方式來(lái)執(zhí)行特定操作時(shí),它非常有用。

我以 onCellClick 為例演示一下如何在 Dojo Grid 上添加自己的處理程序。在本例中,我自定義該方法來(lái)顯示單元格的值以及行和列的索引。(參見清單 13)。


清單 13. 自定義表格的 onCellClick 事件處理程序的 Javascript 代碼
				
<script>
var showDetail = function(e){
                               var value = e.cellNode.firstChild.data;
     alert('value:' + value + " column:" + e.cellIndex + " row:" + e.rowIndex);
            }
            
            dojo.addOnLoad(function(){
                              dojo.connect(grid, "onCellClick", showDetail);
}
</script>            

首先,您需要定義事件處理程序 showDetail 來(lái)顯示單元格詳細(xì)信息(值、列索引和行索引)。接下來(lái),您需要使用 dojo.connect 來(lái)將自定義處理程序連接到 onCellClick 事件。您必須在 dojo.addOnLoad 中執(zhí)行同樣的操作,因?yàn)樵摲椒纱_保所有 Dojo 小部件都已完成初始化并可供使用。

當(dāng)用戶單擊表格的單元格時(shí),應(yīng)用程序?qū)@示一個(gè)警報(bào)窗口。圖 7 顯示了得到的結(jié)果。


圖 7. 表格的自定義事件處理程序
練習(xí)中的表格顯示了一個(gè)彈出對(duì)話框,其中顯示 “value:40 column:4 row:2”

自定義排序

Dojo Grid 提供了根據(jù)列的數(shù)據(jù)類型來(lái)排序的基本排序功能。例如,在我的示例中,ID 列按照數(shù)字順序進(jìn)行排序,名稱列按照字母順序進(jìn)行排序。

Dojo Grid 中的排序功能也可以自定義。您可以定義自定義排序行為或阻止用戶對(duì)某些列排序。如果您不希望用戶對(duì)某些列排序,可以使用 Dojo Grid 的 canSort 屬性來(lái)指定哪些列可以排序。

清單 14 給出了禁用 ID 列的排序功能的 JavaScript 代碼。


清單 14. 指定哪些列可以排序的 Javascript 代碼
				
<script> 
            dojo.addOnLoad(function(){
            		grid.canSort = function(index) {  
			if(index == 1) return false;
			return true;
		};
	}
</script>            

參數(shù)索引為表格的列索引,從 1 開始。如果 canSort 函數(shù)返回 false,則表示禁用了列排序功能。

除了指定哪些列可以排序之外,您還可以指定如何對(duì)列進(jìn)行排序。我在示例中使用 Name 列為例。圖 8 顯示了 Dojo Grid 的默認(rèn)排序行為。


圖 8. Dojo Grid 的默認(rèn)排序行為
此表格中 Name 列中的數(shù)據(jù)以 ASCII 碼降序排列,可以單擊列標(biāo)題中的三角符號(hào)更改排序順序

我按降序?qū)γQ列進(jìn)行排序。請(qǐng)注意最后 3 行:順序?yàn)?Victor、Wang 和 vicky。表格的默認(rèn)排序方式是區(qū)分大小寫的,并使用 ASCII 碼順序進(jìn)行排序。所以,小寫字母將排在大寫字母之后。但是,這種行為不符合軟件全球化標(biāo)準(zhǔn)。在這種情況下,您需要自定義排序函數(shù)來(lái)支持全球化的排序方式。

看一下清單 5 中的 JavaScript 代碼,查看如何自定義 Dojo Grid 的排序函數(shù)。


清單 15. 自定義 Dojo Grid 的排序函數(shù)
				
<script>
            dojo.addOnLoad(function(){
            		myStore.comparatorMap = {};
		myStore.comparatorMap["name"] = function (a, b) {  
			return a.localeCompare(b);
		}
	}
</script>            

數(shù)據(jù)存儲(chǔ)對(duì)象中有一個(gè)名為 comparatorMap 的字段,有了它就可以更改排序行為。在本示例中,我為名稱列定義了一個(gè)比較方法,使用 localeCompare 來(lái)支持全球化排序。圖 9 顯示了經(jīng)過(guò)排序自定義之后的結(jié)果。


圖 9. 自定義的 Dojo Grid 排序行為
此表格顯示的員工信息與圖 8 中相同,但 Name 列按字母降序排列,并且忽略了名稱的大小寫

過(guò)濾器

Dojo Grid 提供一種非常方便的方式來(lái)在客戶端過(guò)濾數(shù)據(jù)。您可以定義一列的過(guò)濾條件。清單 16 展示了如何過(guò)濾表格,僅顯示以字母 A 開頭的名稱。


清單 16. 過(guò)濾名稱列
				
<div dojoType="dijit.form.Button">filter name
	<script type="dojo/method" event="onClick" args="evt">
	// Filter the name from the data store:
		grid.filter({name: "A*"});
	</script>
</div>            

單擊 filter name 按鈕之后,過(guò)濾結(jié)果將如圖 10 所示。


圖 10. 經(jīng)過(guò)過(guò)濾的表格
單擊底部的 “filter name” 按鈕之后表格中顯示的數(shù)據(jù)集,列表中僅包含:Alex 和 Alice

結(jié)束語(yǔ)

本文通過(guò) MVC 設(shè)計(jì)模式介紹了 Dojo Grid 的主要功能。通常,可以采用多種方式實(shí)現(xiàn)一項(xiàng)功能。例如,要在表格中顯示日期,既可以使用字符串來(lái)在數(shù)據(jù)存儲(chǔ)中表示日期,也可以聲明一個(gè) long 并在最終顯示中為其設(shè)置正確的格式。咋看起來(lái),第一種選擇似乎更簡(jiǎn)單。但是,如果需要使表格全球化,后一種選擇更好。希望您在自己的 Dojo Grid 項(xiàng)目中使用 MVC 設(shè)計(jì)模式。您將會(huì)進(jìn)一步提高代碼的健壯性和可重用性。


參考資料

作者簡(jiǎn)介

http://www.ibm.com/developerworks/i/p-llou.jpg

Luo Ling 是一名致力于 Dojo 開發(fā)和訪問(wèn)技術(shù)的專家。

Jin Pan 自 2006 年就開始在 IBM 中國(guó)研發(fā)實(shí)驗(yàn)室工作,曾參與并領(lǐng)導(dǎo)了多個(gè) J2EE 項(xiàng)目。她對(duì) Dojo 和 Web 2.0 等新興 Web 技術(shù)興趣濃厚。她分別于 2003 年和 2006 年從復(fù)旦大學(xué)獲得了計(jì)算機(jī)科學(xué)理學(xué)學(xué)士學(xué)位和理學(xué)碩士學(xué)位。

Qiang Guo Tong 是一位資深軟件工程師,在 Web 開發(fā)領(lǐng)域擁有 5 年豐富經(jīng)驗(yàn)。他是在 IBM 使用的多個(gè)全球性工具研發(fā)工作的技術(shù)領(lǐng)導(dǎo)。

http://www.ibm.com/developerworks/i/p-dwang.jpg

Dan Wang 自 2006 年開始就在 IBM 中國(guó)研發(fā)實(shí)驗(yàn)室工作,曾參與多個(gè) J2EE 項(xiàng)目。他對(duì) Dojo 和 Web 2.0 等新興 Web 技術(shù)興趣濃厚。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多