在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文用 ASP.NET MVC 5 實作一個 GridView,功能包括: 分頁(paging)、關鍵字過濾(filtering)、排序(sorting)、AJAX 非同步執行,外觀上亦支援 Responsive Web Design (響應式網頁)。執行畫面,如下圖 1。 -------------------------------------------------
using System.ComponentModel.DataAnnotations; namespace NorthwindPaging.Models { public class Order { public int OrderID { get; set; } [Display(Name = "客戶 ID")] public string CustomerID { get; set; } [Display(Name = "員工 ID")] public decimal EmployeeID { get; set; } [Display(Name = "運送國別")] public string ShipCountry { get; set; } [Display(Name = "運送費用")] public decimal Freight { get; set; } } } 接著打開 Models/IdentityModels.cs 這支檔案,裡面是 ASP.NET identity 2.0 的相關功能。我們加入以下這一行 Order 資料表的 property 程式: public DbSet<Order> Orders { get; set; } //自訂類別 Order 接著在 Controller 層,新增一個命名為 OrderController 的空白「控制器」。
裝著要透過 NuGet 安裝 jQuery datatables,如下圖 2。 圖 2 安裝 jQuery datatables // jquery datataables js files bundles.Add(new ScriptBundle("~/bundles/datatables").Include( "~/Scripts/DataTables/jquery.dataTables.min.js", "~/Scripts/DataTables/dataTables.bootstrap.js")); // jquery datatables css file bundles.Add(new StyleBundle("~/Content/datatables").Include( "~/Content/DataTables/css/dataTables.bootstrap.css")); 接著在 Views/Shared/_Layout.cshtml,加入以下兩行程式碼: @Styles.Render("~/Content/datatables")
@Scripts.Render("~/bundles/datatables")
裝著要透過 NuGet 安裝 datatables.mvc5,如下圖 3。 圖 3 安裝 datatables.mvc5
首先,在 Web.config 的資料庫連線字串 DefaultConnection 中,手動加入 Northwind 的連線設定。 private ApplicationDbContext _dbContext; public ApplicationDbContext DbContext { get { return _dbContext ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>(); } private set { _dbContext = value; } }
在 Views/Order 資料夾裡,加入一個空白的「檢視」,網頁命名為 OrderGridView (或任何名稱)。接著清空 OrderGridView.cshtml 的所有內容 (jQuery datatables 會自動產生 head、body 等 tag),手動加入以下 HTML tag: <div class="row"> <div class="col-md-12"> <div class="panel panel-primary list-panel" id="list-panel"> <div class="panel-heading list-panel-heading"> <h1 class="panel-title list-panel-title">Orders 資料表</h1> </div> <div class="panel-body"> <table id="orders-data-table" class="table table-striped table-bordered" style="width:100%;"></table> </div> </div> </div> </div> 接著繼續在 OrderGridView.cshtml 裡,手動加入以下的程式,以便用 AJAX 方式,由 server-side 從資料庫撈出畫面上,該頁要呈現的資料: @section Scripts { <script type="text/javascript"> var orderListVM; $(function () { orderListVM = { dt: null, init: function () { dt = $('#orders-data-table').DataTable({ "serverSide": true, "processing": true, "ajax": { "url": "@Url.Action("Get","Order")" }, "columns": [ { "title": "Order ID", "data": "OrderID", "searchable": true }, { "title": "Customer ID", "data": "CustomerID", "searchable": true }, { "title": "Employee ID", "data": "EmployeeID", "searchable": true }, { "title": "Ship Country", "data": "ShipCountry", "searchable": true }, { "title": "Freight", "data": "Freight", "searchable": true } ], "lengthMenu": [[10, 25, 50, 100], [10, 25, 50, 100]], }); } } // initialize the datatables orderListVM.init(); }); </script> } 上方程式碼中,serverSide": true,表示 paging、filtering、sorting 要依使用者每次的操作,從 server-side 去取得;而非一次將符合 SELECT WHERE 條件的資料全部撈出,再由 client-side 去處理 (若資料量過大,會拖垮效能)。
本範例的 sorting 有用到 Dynamic LINQ 的語法 (非必要,只是為了簡化 sorting 的程式碼),此功能要額外安裝。我們透過 NuGet 安裝 Dynamic LINQ,如下圖 4。
接下來撰寫 OrderController 裡,Get 這個 Action 方法,程式碼如下: public ActionResult Get([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel) { IQueryable<Order> query = DbContext.Orders; //LINQ to Entites var totalCount = query.Count(); //Order 資料表全部 830 筆 #region Filtering (使用者輸入關鍵字搜尋) // Apply filters for searching (DataTables.Mvc.Search 類別) if (requestModel.Search.Value != string.Empty) { var value = requestModel.Search.Value.Trim(); //filtering 功能 (欄位必須要 string,欄位 int、decimal 預設不行,因此加上ToString()) query = query.Where(o => o.OrderID.ToString().Contains(value) || o.CustomerID.Contains(value) || o.EmployeeID.ToString().Contains(value) || o.ShipCountry.Contains(value) || o.Freight.ToString().Contains(value) ); } var filteredCount = query.Count(); //全部 830 筆 #endregion Filtering #region Sorting var sortedColumns = requestModel.Columns.GetSortedColumns(); var orderByString = String.Empty; foreach (var column in sortedColumns) { orderByString += orderByString != String.Empty ? "," : ""; orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc"); } //Dynamic LINQ query = query.OrderBy(orderByString == string.Empty ? "OrderID asc" : orderByString); //預設的排序欄位、排序方式 #endregion Sorting #region Paging query = query.Skip(requestModel.Start).Take(requestModel.Length); //Skip:起始index,Take:要撈的筆數(使用者可由下拉選單選擇) int i1 = query.Count(); //已用 SQL Server 的 OFFSET-FETCH 或 ROW_NUMBER(),過濾出畫面上該頁要顯示的 10 筆 //用 Select() 重新組裝我們需要的資料 var data = query.Select(order => new { OrderID = order.OrderID, CustomerID = order.CustomerID, EmployeeID = order.EmployeeID, ShipCountry = order.ShipCountry, Freight = order.Freight }).ToList(); #endregion Paging int i2 = query.Count(); //10 int i3 = data.Count(); //10 int i4 = requestModel.Draw; //1、2、...(非頁數) int i5 = requestModel.Start; //起始index,第1頁為0、第2頁為10、第4頁為30、... int i6 = requestModel.Length; //10. tells how many records per page user wants to see which is also configurable by user using combo box int i7 = filteredCount; // 830 筆 int i8 = totalCount; // 830 筆 //參數1:datatables.mvc5 的自訂類別 DataTablesResponse, 參數2:允許 HTTP GET 存取 return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet); } 這個自訂的 Get 方法,回傳的是 JsonResult。其中第一個參數,是第三方元件 datatables.mvc5 的自訂類別 DataTablesResponse。若我們在前端 OrderGridView.cshtml 裡,所撰寫的對應 columns 沒錯的話,GridView 即可正常顯示資料。且由於 jQuery datatables 支援 Bootstrap,因此這個 GridView 外觀上亦支援 RWD (響應式網頁),以行動裝置瀏覽時,畫面會自動縮放。
jQuery datatables 中的文字訊息是英文,若要改成中文,可自行開啟 Scripts\DataTables\jquery.dataTables.min.js 這支檔案,手動進行修改,執行結果如圖 1 左下方頁碼列的「顯示」字樣。
若我們開啟 SQL Profiler,觀察畫面上換頁時所執行的 T-SQL 語句,會發現 LINQ 已處理好資料庫撈資料時的「分頁」問題,可避免像過去 WebForm 時代,要自己撰寫,處理 paging 的 SQL 語句或 Stored Procedure [4]。 SELECT [Extent1].[OrderID] AS [OrderID], [Extent1].[CustomerID] AS [CustomerID], [Extent1].[EmployeeID] AS [EmployeeID], [Extent1].[ShipCountry] AS [ShipCountry], [Extent1].[Freight] AS [Freight] FROM [dbo].[Orders] AS [Extent1] ORDER BY [Extent1].[OrderID] ASC OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY SELECT [Extent1].[OrderID] AS [OrderID], [Extent1].[CustomerID] AS [CustomerID], [Extent1].[EmployeeID] AS [EmployeeID], [Extent1].[ShipCountry] AS [ShipCountry], [Extent1].[Freight] AS [Freight] FROM [dbo].[Orders] AS [Extent1] ORDER BY [Extent1].[OrderID] ASC OFFSET 30 ROWS FETCH NEXT 10 ROWS ONLY
[1] GridView with Server Side Filtering, Sorting and Paging in ASP.NET MVC 5 (server-side)
[4] ASP.NET 数据分页第一篇 - 探讨分页原理及 SQL Server 2005 的 ROW_NUMBER 函数
|
请发表评论