在之前的一篇文章中,我們討論了如何添加一大堆的超贊的功能到一個標准的HTML表,並把它轉換成一個“grid”表格。今天我想要做的事情是向你展示如何將這些功能轉到服務器。
通過使用服務器做大量的“苦力活兒”,我們可以向我們的最終用戶提供更加平順的用戶體驗。什么苦力活要交給服務器呢?假設你有一百萬行的數據集,這些數據要是發送到客戶端,然后再進行排序/分頁/過濾,那會是相當可觀的一堆流量。但是如果我們要求服務器在發送數據到客戶端之前執行排序/分頁/過濾,我們可以迅速的減少客戶端的開銷。
服務器
關於數據,我使用Chinook數據庫。它速度快,容易設置,同時可以給我的例子提供很好的數據。我在例子中使用到了ASP.NET MVC3,並且我們只實現排序和過濾。
public JsonResult GetAlbumList() { int pageSize = Request.Params["paging[pageSize]"] != null ? Convert.ToInt32(Request.Params["paging[pageSize]"]) : 0; int pageIndex = Request.Params["paging[pageIndex]"] != null ? Convert.ToInt32(Request.Params["paging[pageIndex]"]) : 0; string sortColumn = Request.Params["sorting[0][dataKey]"]; string sortDirection = Request.Params["sorting[0][sortDirection]"]; if (string.IsNullOrEmpty(sortColumn)) sortColumn = String.Empty; if (string.IsNullOrEmpty(sortDirection)) sortDirection = String.Empty; using (var entity = new ChinookEntities()) { var allAlbums = from al in entity.Albums join ar in entity.Artists on al.ArtistId equals ar.ArtistId select new AlbumResult() { AlbumName = al.Title, ArtistName = ar.Name }; var totalRowCount = allAlbums.Count(); if (pageSize == 0) pageSize = totalRowCount; if (sortColumn.ToLower() != "album") allAlbums = sortDirection.ToLower() == "descending" ? allAlbums.OrderByDescending(p => p.ArtistName).Skip(pageSize*pageIndex).Take(pageSize) : allAlbums.OrderBy(p => p.ArtistName).Skip(pageSize*pageIndex).Take(pageSize); else allAlbums = sortDirection.ToLower() == "descending" ? allAlbums.OrderByDescending(p => p.AlbumName).Skip(pageSize*pageIndex).Take(pageSize) : allAlbums.OrderBy(p => p.AlbumName).Skip(pageSize*pageIndex).Take(pageSize); var result = new WijmoGridResult { Items = allAlbums.ToList(), TotalRowCount = totalRowCount }; return Json(result, JsonRequestBehavior.AllowGet); } }
讓我們一行一行的看一看這些代碼都作了些什么,因為他確實做了很多事情!最初的六行抽取了Wijmo需要發送的Request參數。因為很有可能這些值為空,一點點的參數檢查邏輯是必須的。
從using表達式開始,我們使用Entity Framework打開一個到我們數據庫的鏈接。我們使用延遲加載的想法對創建結構化查詢,因此和SQL服務器的交互只有一次。第一次查詢創建對數據庫中所有相冊的查詢。獲取所有行的個數是必須的。Wijmo會使用這個結果判斷分頁需求。
關於排序,你也許已經被巨復雜的IF..ELSE表達式折磨得疲憊不堪。所有這些邏輯僅僅是為了判斷我們要基於哪一列進行排序以及按照何種方式(升序或者降序)進行排列,同時應用LINQ過濾。這些調用同時也使用了Skip()以及Take()技術進行分頁。
最后,你可能注意到了我還沒有給出AlbumReult以及WijmoGridResult的定義。以下是這些類的代碼:
public class AlbumResult { public string AlbumName { get; set; } public string ArtistName { get; set; } } public class WijmoGridResult { public List Items { get; set; } public int TotalRowCount { get; set; } }
客戶端
現在服務器端已經配置好了,我們需要改變一點Wijmo的配置以以便使用這些新設置。
$(document).ready(function () { var dataReader = new wijarrayreader([ { name: "Artist", mapping: "ArtistName" }, { name: "Album", mapping: "AlbumName" } ]); var dataSource = new wijdatasource({ proxy: new wijhttpproxy({ url: "@Url.Action("GetAlbumList")", dataType: "json" }), dynamic: true, reader: { read: function (datasource) { var count = datasource.data.TotalRowCount; datasource.data = datasource.data.Items; datasource.data.totalRows = count; dataReader.read(datasource); } } }); $("#remoteTable").wijgrid({ pageSize: 15, data: dataSource, allowPaging: true, allowSorting: true }); });
在最開始,我們打算聲明一個新的datareader,用來讀取來自服務器的JSON數據。它將告訴Wijmo如何將JSON屬性映射到表格的列。
接下來是數據源。這是一個URL的代理。Wijmo會在這個URL上做一個GET操作以獲取信息。這里dynamic關鍵字告訴Wijmo,服務器會接受排序,過濾以及分頁請求。如果它被設置為false或者從來都沒有設置過,Wijmo不會發送我們之前提到的請求參數。Reader告訴Wijmo如何解釋數據,並且獲取行數,之后是應用darareader。
最后一個調用是真正的創建WijGrid。這和你之前曾經看過的沒有什么不同。唯一使得服務器收集數據的設置就是datasource。