刷微博已經成為大家的一種生活方式,我今天要介紹的功能就很類似刷微博。
當我們需要將大數據(比如百萬條數據)顯示在頁面上的時候,顯然一次加載是不現實的,用戶體驗很差。當然,你可能會想到采用分也顯示,但是現在的用戶已經
厭倦了分頁的方式,他們更喜歡刷微博的方式。
於是就出現了這篇文章。
筆者近期的項目中,采用的前端框架是ExtJs,其提供的GridPanel足以應付一次性加載500+以上的記錄,只是會讓用戶等待一會。
但是日志的顯示沒那么簡單,其數據一直在增加,用戶也不想分頁查看,而是用傳統的GridPanel也不太適合。
Google之后,原來ExtJs已經提供了一個插件(Ext.ux.grid.livegrid),強大的Extjs啊!
據說ExtJs 4 提供了一個更加好用的插件來替代這個插件,由於時間關系,筆者僅僅使用了ext 2.2 和 ext 3.3.1兩個版本的,效果還不錯,
慣例先上圖
筆者測試八百萬條數據,只需要等待1秒左右,當然那是首次加載的速度。而且我們不是一次加載的。
上代碼吧,
這里使用的是Extjs2.2版本,筆者也用了3.3.1的版本,貌似還要簡潔很多,但是demo在公司。
Views:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Index</title> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <link rel="Stylesheet" type="text/css" href="../../Scripts/Ext/resources/css/ext-all.css" /> <link rel="Stylesheet" type="text/css" href="../../Scripts/Ext/resources/css/ext-ux-livegrid.css" /> <link href="../../Content/css.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../../Scripts/Ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="../../Scripts/Ext/ext-all.js"></script> <script type="text/javascript" src="../../Scripts/Ext/GridPanel.js"></script> <script type="text/javascript" src="../../Scripts/Ext/GridView.js"></script> <script type="text/javascript" src="../../Scripts/Ext/RowSelectionModel.js"></script> <script type="text/javascript" src="../../Scripts/Ext/Store.js"></script> <script type="text/javascript" src="../../Scripts/Ext/Toolbar.js"></script> <script type="text/javascript" src="../../Scripts/Ext/JsonReader.js"></script> <script type="text/javascript" src="../../Scripts/Ext/ext-lang-zh_CN.js"></script> <script type="text/javascript" src="../../Scripts/js/grid.js"></script> <script src="../../Scripts/js/CHelper.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> Ext.onReady(function () { Ext.BLANK_IMAGE_URL = 'Ext/resources/images/default/tree/s.gif'; showMe(); }); </script> </head> <body> <div id="content"> </div> </body> </html>
Controllers:

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using LiveGrid.Models; namespace LiveGrid.Controllers { public class DefaultController : Controller { // // GET: /Default/ public ActionResult Index() { return View(); } #region 獲取LiveGrid Data /// <summary> /// 獲取LiveGrid Data /// </summary> /// <returns></returns> public JsonResult GetLiveGridData() { var starts = null == Request["starts"] ? "0" : Request["starts"]; var limits = null == Request["limits"] ? "300" : Request["limits"]; var oLiveGridData = GetLiveData(int.Parse(starts),int.Parse(limits)); return Json(oLiveGridData,JsonRequestBehavior.AllowGet); } #endregion #region 獲取LiveGridData對象 /// <summary> /// 獲取LiveGridData對象 /// </summary> /// <param name="starts"></param> /// <param name="limits"></param> /// <returns></returns> public CLiveGridData GetLiveData(int starts, int limits) { var oLiveGridData = new CLiveGridData(); //總數據 var lstData = GetLstData(); //分頁數據 var lstNeedData = GetLstDataByWhere(lstData,starts,limits); oLiveGridData.totalCount = lstData.Count; oLiveGridData.success = true; oLiveGridData.error = string.Empty; oLiveGridData.singleInfo = string.Empty; var oData = new List<Dictionary<string, string>>(); foreach(var oPerson in lstNeedData) { var dicPerson = new Dictionary<string, string>(); dicPerson.Add("coname", oPerson.coname); dicPerson.Add("coarea", oPerson.coarea); dicPerson.Add("phonenumber", oPerson.phonenumber); oData.Add(dicPerson); } oLiveGridData.data = oData; return oLiveGridData; } #endregion #region 構造數據 /// <summary> /// 構造數據 /// </summary> /// <returns></returns> public List<CDataModel> GetLstData() { var lstData = new List<CDataModel>(); for (var iIndex = 0; iIndex < 8000000;iIndex++ ) { var oDataModel = new CDataModel(); oDataModel.coname = string.Format("{0}{1}","LuckyHu",iIndex); oDataModel.coarea = "ChengDu"; oDataModel.phonenumber = "1878028****"; lstData.Add(oDataModel); } return lstData; } #endregion #region 獲取分頁數據 /// <summary> /// 獲取分頁數據 /// </summary> /// <param name="lstData"></param> /// <param name="starts"></param> /// <param name="limits"></param> /// <returns></returns> public List<CDataModel> GetLstDataByWhere(List<CDataModel> lstData, int starts, int limits) { var lsNeedData = new List<CDataModel>(); var iMax = starts + limits; for (var iIndex = starts; iIndex < iMax;iIndex++ ) { lsNeedData.Add(lstData[iIndex]); } return lsNeedData; } #endregion } }
為了適配不同的表結構的數據,筆者設計了一個類,適配該控件
Models

using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace LiveGrid.Models { public class CLiveGridData { public int totalCount; public bool success; public string error; public string singleInfo; //public List<CDataModel> data; public List<Dictionary<string, string>> data; } public class CDataModel { public string coname; public string coarea; public string phonenumber; } }
優化的地方還多,呵呵 感謝前輩 OoLaLa 提供的參考http://www.cnblogs.com/xuchongyao/archive/2009/11/29/1612886.html
demo下班在弄上去,先上班去了!!!