首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET MVC 結合 EF 實現服務端分頁:jqGrid 與 jQuery DataTables 實戰避坑指南

     編輯:ASP.NET 基礎

項目背景與技術選型

計劃構建個人博客系統,技術棧鎖定為 ASP.NET MVC5 + EF6 (Code First) + ZUI + jQuery 插件生態。ZUI 作為基於 Bootstrap 深度定制的國產前端框架,上手較快且適配國內環境。但在表格組件選型上陷入糾結:ZUI 僅提供基礎表格樣式,分頁、排序等交互需自行對接 JS 插件。經調研,主流選擇集中在 jqGrid 與 jQuery DataTables,兩者各有優劣,本文記錄雙方在服務端分頁集成中的關鍵配置與踩坑經驗。

方案一:jqGrid 服務端分頁集成

核心參數映射

前端參數含義後端對應
rows每頁記錄數pageSize
page當前頁碼(從 1 開始)pageIndex
sidx排序列sortField
sord排序方向sortOrder

後端返回數據格式

// JsonResult 返回結構
return Json(new {
    total = totalPages,      // 總頁數
    page = pageIndex,        // 當前頁碼
    records = totalRecords,  // 總記錄數
    rows = dataList          // 當前頁數據集合
}, JsonRequestBehavior.AllowGet);

關鍵分頁邏輯

var query = dbContext.Set<T>().Where(whereLambda);
// 總記錄數
int totalRecords = query.Count();
// 總頁數
int totalPages = (int)Math.Ceiling((double)totalRecords / pageSize);
// 分頁查詢:跳過 + 獲取
var data = query.OrderBy(sortField + " " + sortOrder)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .ToList();

前端初始化要點

$("#grid").jqGrid({
    url: '/JQGrid/GetData',
    datatype: 'json', // 注意:MVC 返回純 JSON,非 jsonp
    mtype: 'GET',
    colModel: [ /* 列定義 */ ],
    rowNum: 10,
    pager: '#pager',
    viewrecords: true
});

避坑提示:官方 Demo 多用 PHP + jsonp,MVC 必須設置 datatype: 'json',否則會因跨域回調失敗導致數據不顯示。

方案二:jQuery DataTables 服務端分頁集成

核心參數差異(與 jqGrid 最大不同點)

DataTables 參數含義jqGrid 對應
draw繪制計數器(防異步亂序)無
start起始記錄索引(從 0 開始)page (從 1 開始)
length每頁記錄數rows
order[i][column]排序列索引sidx
order[i][dir]排序方向sord
search[value]全局搜索值_search + searchString

後端返回格式

return Json(new {
    draw = draw,                 // 必須原樣返回
    recordsTotal = totalRecords, // 總記錄數(無過濾)
    recordsFiltered = filtered,  // 過濾後總數
    data = dataList              // 數據數組
}, JsonRequestBehavior.AllowGet);

致命坑:start 參數導致 Skip 計算為負數

DataTables 首次請求傳 start=0,若直接套用 jqGrid 的 Skip((page-1)*size) 邏輯:

// 錯誤寫法
int page = start / length + 1; // start=0 時 page=1
var data = query.Skip((page - 1) * length).Take(length); // Skip(0) 正常

// 但若誤以為 start 是頁碼:
var data = query.Skip((start - 1) * length).Take(length); // start=0 時 Skip(-10) 拋異常!

正確處理:

// start 是記錄偏移量,直接用於 Skip
int skip = start; // 無需 -1
var data = query.OrderBy(...).Skip(skip).Take(length).ToList();

完整後端 Action 示例

[HttpPost]
public ActionResult GetData(DataTablesParam param) {
    var query = db.Set<Entity>().AsQueryable();
    
    // 總記錄數
    int totalRecords = query.Count();
    
    // 搜索過濾
    if (!string.IsNullOrEmpty(param.search.value)) {
        query = query.Where(x => x.Name.Contains(param.search.value) 
                              || x.Code.Contains(param.search.value));
    }
    int filteredRecords = query.Count();
    
    // 排序
    var sortCol = param.columns[param.order[0].column].data;
    var sortDir = param.order[0].dir; // asc/desc
    query = query.OrderBy(sortCol + " " + sortDir);
    
    // 分頁
    var data = query.Skip(param.start).Take(param.length).ToList();
    
    return Json(new {
        draw = param.draw,
        recordsTotal = totalRecords,
        recordsFiltered = filteredRecords,
        data = data
    });
}

// DataTables 參數模型綁定類
public class DataTablesParam {
    public int draw { get; set; }
    public int start { get; set; }
    public int length { get; set; }
    public List<ColumnDef> columns { get; set; }
    public List<OrderDef> order { get; set; }
    public SearchDef search { get; set; }
}
public class ColumnDef { public string data { get; set; } }
public class OrderDef { public int column { get; set; } public string dir { get; set; } }
public class SearchDef { public string value { get; set; } }

兩者對比與選型建議

維度jqGridjQuery DataTables
學習曲線中等,配置項多較低,API 更直觀
服務端模式參數page/rows (頁碼制)start/length (偏移量制)
異步請求序列保證無內建機制draw 計數器自動處理
內建功能豐富度極高(子表格、分組、凍結列等)高(需插件擴展部分高級功能)
社區活躍度成熟穩定,更新較慢非常活躍,生態豐富
樣式適配需額外引入 Bootstrap 主題原生支持 Bootstrap/Foundation

選型建議

  • 選 jqGrid:需要複雜的表格功能(如樹形表格、可編輯單元格、主從表聯動),且團隊有舊版維護經驗。
  • 選 DataTables:現代項目、追求開發效率、需良好移動端適配、偏好語義化 API、需要前端即時搜索/排序降級體驗。

總結

服務端分頁的核心在於參數映射正確與返回格式標準。jqGrid 的頁碼制與 DataTables 的偏移量制是最大認知差異點,搞清 start 從 0 開始且直接等於 Skip 參數,即可避開 90% 的坑。無論選擇哪款插件,建議封裝通用的 PagedResult<T> 返回模型與 DataTablesParam 綁定模型,提升復用性與可維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved