在 MVC 中使用 jQuery Grid 插件的示例 - 第 1 部分
本文提供了一个在 MVC 中使用 jQuery Grid 插件的简单示例。
引言
背景
这是文章的第一部分,演示了如何使用“jQuery Grid Plugin”插件。该示例将向您展示如何实现一个只读网格。本文试图回答以下问题:
- 要使用“jQuery Grid Plugin”插件,需要下载的最少 JavaScript 库和 CSS 样式有哪些?
- 如何实现一个基本的网格?
- 如何为网格实现分页、排序和搜索功能?
“jQuery Grid Plugin”插件使用“Ajax”调用从服务器获取数据进行显示。我们可以使用许多平台,例如“PHP”,来实现服务器代码来处理“Ajax”调用。在本例中,服务器代码是用 ASP.NET “MVC”控制器实现的。
本文假定您已经具备“jQuery”和“MVC”的一些基本知识。如果您对这些主题不熟悉,可以很容易地在互联网上找到参考资料。
Visual Studio 解决方案

要使用“jQuery Grid Plugin”插件创建一个功能最少的网格,您需要下载以下组件:
- 您需要“jQuery”脚本库。您可以从 这里 下载。本示例中使用的是版本“1.6.2”。
- 您需要“jQuery Grid Plugin”插件的脚本库和一些 CSS 样式。您可以从 这里 下载。至少,您需要两个 JavaScript 文件“jquery.jqGrid.min.js”和“grid.locale-en.js”。您还需要 CSS 文件“ui.jqgrid.css”。本示例中使用的“jQuery Grid Plugin”插件版本为“4.1.2”。
- “jQuery Grid Plugin”插件使用“jQuery UI”的一些 CSS 样式。您可以从 这里 下载“jQuery UI”。要创建一个基本网格,您不需要“jQuery UI”的 JavaScript 文件。您只需要 CSS 样式。“jQuery UI”的 CSS 样式有不同的“主题”。本示例中使用的是“redmond”主题。本示例使用的 CSS 样式来自版本“1.8.14”。
在解决方案资源管理器中,您可以看到我将所有下载的 JavaScript 文件放在“Scripts”文件夹中,并将所有下载的 CSS 样式表和图像文件放在“Content”文件夹中。除了下载的文件之外,以下文件与在此示例中使用“jQuery Grid Plugin”插件创建网格相关:
- “Models”文件夹中的“StudentRepository.cs”是应用程序的数据模型。它维护着供网格显示的数据。
- “Default.htm”是创建网格的文件。它包含创建网格所需的 HTML 组件和 JavaScript 代码。
- “Controllers”文件夹中的 MVC 控制器“jQGridController.cs”实现了服务器代码,用于处理“jQuery Grid Plugin”插件发出的“Ajax”调用。
“Controllers”文件夹中的 MVC 控制器“HomeController.cs”的唯一目的是使“Default.htm”文件成为此 MVC 应用程序的默认网页。如果用户在 URL 中未指定控制器和操作,则此文件负责将其重定向到“Default.htm”页面。“HomeController.cs”的实现如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace jqGridExamplePart1.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
// Always re-direct to the "Default.htm" page
return new RedirectResult(Url.Content("~/Default.htm"));
}
}
}
现在让我们看看如何使用“jQuery Grid Plugin”插件创建一个只读网格,从应用程序的数据模型开始。
数据模型
应用程序的数据模型在“Models”文件夹中的“StudentRepository.cs”中实现。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace jqGridExamplePart1.Models
{
// The student class
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Score { get; set; }
public DateTime Enrollment { get; set; }
}
// This static class serves as a repository of the student collection
public static class StudentRepository
{
private static readonly List<Student> Students = new List<Student>();
public static List<Student> GetStudents() { return Students; }
// Static constructor to initiate some students in the repository
static StudentRepository()
{
int total = 105;
DateTime now = DateTime.Now;
var scoreRand = new Random();
var enrollmentRand = new Random();
for (int i = 1; i <= total; i++)
{
var student = new Student();
student.Id = i;
student.Name = "Name No." + i.ToString();
student.Score = 60
+ Convert.ToInt16(scoreRand.NextDouble() * 40);
student.Enrollment
= now.AddDays(-1 * (int)(enrollmentRand.NextDouble() * 365 * 10));
Students.Add(student);
}
}
}
}
- “
Student
”类定义了一些学生的基本信息。 static
类“StudentRepository
”维护一个学生列表。我们可以使用“GetStudents
”方法访问学生列表。
在本示例中,将在“Default.htm”页面中创建的网格中显示“StudentRepository
”类中的学生列表。
“Default.htm”页面
“Default.htm”页面的实现如下:
<!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>
<title>jqGrid Example Part 1</title>
<link rel="stylesheet"
href="Content/jquery-ui/redmond/jquery-ui-1.8.14.custom.css"
type="text/css" />
<link rel="stylesheet"
href="Content/jquery-grid/ui.jqgrid.css" type="text/css" />
<script src="Scripts/jquery-1.6.2.min.js"
type="text/javascript"></script>
<script src="Scripts/jquery-grid/grid.locale-en.js"
type="text/javascript"></script>
<script src="Scripts/jquery-grid/jquery.jqGrid.min.js"
type="text/javascript"></script>
<script type="text/javascript">
// the url to make the Ajax calls
var jqDataUrl = "jQGrid/LoadjqData";
$(document).ready(function () {
// Set up the jquery grid
$("#jqTable").jqGrid({
// Ajax related configurations
url: jqDataUrl,
datatype: "json",
mtype: "POST",
// Specify the column names
colNames: ["Id", "Name", "Score", "Enrollment"],
// Configure the columns
colModel: [
{ name: "Id", index: "Id", width: 40, align: "left" },
{ name: "Name", index: "Name", width: 100, align: "left" },
{ name: "Score", index: "Score", width: 200, align: "left" },
{ name: "Enrollment", index: "Enrollment", width: 200, align: "left"}],
// Grid total width and height
width: 550,
height: 200,
// Paging
toppager: true,
pager: $("#jqTablePager"),
rowNum: 5,
rowList: [5, 10, 20],
viewrecords: true, // Specify if "total number of records" is displayed
// Default sorting
sortname: "Id",
sortorder: "asc",
// Grid caption
caption: "A Basic jqGrid - Read Only"
}).navGrid("#jqTablePager",
{ refresh: true, add: false, edit: false, del: false },
{}, // settings for edit
{}, // settings for add
{}, // settings for delete
{sopt: ["cn"]} // Search options. Some options can be set on column level
);
});
</script>
</head>
<body>
<div>
<table id="jqTable" class="scroll"></table>
<div id="jqTablePager" />
</div>
</body>
</html>
- 从网上下载的 JavaScript 和 CSS 文件在“Default.htm”文件的开头被引用。
- HTML“
table
”的“jqTable
”和 HTML “div
”的“jqTablePager
”是生成网格所需的 HTML 元素。 - 在“
$(document).ready
”事件中,JavaScript 代码调用“jQuery Grid Plugin”插件的“jqGrid()
”函数来创建网格。
创建网格时,我们可以通过一个“Json”对象将许多参数传递给“jqGrid()
”函数。在本例中,我向该函数传递了以下信息:
- 供“jQuery Grid Plugin”插件发出“Ajax”调用的参数。在本例中,网格与服务器的所有调用都将转到“
jQGrid
”控制器中的“LoadjqData
”操作方法。 - 网格中列的名称。
- 通过“
colModel
”参数为每列进行的配置信息。 - 分页所需的信息。
- 默认情况下,网格中的所有列都启用了排序。我们只需要指定默认的排序列和排序顺序。
在对“navGrid()
”的函数调用中,我们可以进一步配置网格的行为。为了简单起见,我禁用了编辑功能,以便我们可以专注于使用“jQuery Grid Plugin”插件创建只读网格。默认情况下,网格的搜索功能是启用的,并且“jQuery Grid Plugin”插件提供了大量的搜索操作。在本例中,我将仅演示如何通过限制“sopt
”参数的搜索选项来实现“contains
”类型的搜索。
“jQGridController”控制器
将数据发送到网格进行显示的服务器代码实现在“jQGridController.cs”中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using jqGridExamplePart1.Models;
using System.Linq.Expressions;
namespace jqGridExamplePart1.Controllers
{
public class jQGridController : Controller
{
[HttpPost]
public ActionResult LoadjqData(string sidx, string sord, int page, int rows,
bool _search, string searchField, string searchOper, string searchString)
{
// Get the list of students
var students = StudentRepository.GetStudents().AsQueryable();
// If search, filter the list against the search condition.
// Only "contains" search is implemented here.
var filteredStudents = students;
if (_search)
{
filteredStudents = students.Where(s =>
(typeof(Student).GetProperty(searchField).GetValue
(s, null) == null) ? false :
typeof(Student).GetProperty(searchField).GetValue(s, null)
.ToString().Contains(searchString));
}
// Sort the student list
var sortedStudents = SortIQueryable<Student>(filteredStudents, sidx, sord);
// Calculate the total number of pages
var totalRecords = filteredStudents.Count();
var totalPages = (int)Math.Ceiling((double)totalRecords / (double)rows);
// Prepare the data to fit the requirement of jQGrid
var data = (from s in sortedStudents
select new
{
id = s.Id,
cell = new object[] { s.Id, s.Name,
s.Score, s.Enrollment.ToString("MM/dd/yyyy") }
}).ToArray();
// Send the data to the jQGrid
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = data.Skip((page - 1) * rows).Take(rows)
};
return Json(jsonData);
}
// Utility method to sort IQueryable given a field name as "string"
// May consider to put in a central place to be shared
private IQueryable<T> SortIQueryable<T>(IQueryable<T> data,
string fieldName, string sortOrder)
{
if (string.IsNullOrWhiteSpace(fieldName)) return data;
if (string.IsNullOrWhiteSpace(sortOrder)) return data;
var param = Expression.Parameter(typeof(T), "i");
Expression conversion = Expression.Convert
(Expression.Property(param, fieldName), typeof(object));
var mySortExpression = Expression.Lambda<Func<T, object>>(conversion, param);
return (sortOrder == "desc") ? data.OrderByDescending(mySortExpression)
: data.OrderBy(mySortExpression);
}
}
}
在本例中,“jQuery Grid Plugin”插件将发出“Ajax”调用到“LoadjqData
”操作方法以获取显示在网格中的数据。所有到服务器的“Ajax”调用都是由“jQuery Grid Plugin”插件自动发起的,我们不需要在代码中直接调用“$.ajax()
”方法来设置网格。“Ajax”调用将通过函数参数传递服务器准备数据所需的所有信息,例如排序、分页和搜索所需的信息。利用函数参数中的信息,“LoadjqData
”方法执行以下步骤将数据发送到网格:
- 它首先从“
StudentRepository
”检索整个学生列表。 - 如果需要搜索,它将根据搜索条件获取学生子集。
- 然后对过滤后的学生列表进行排序,并计算显示给定页面大小的数据所需的总页数。
- 最后,它将数据准备成“jQuery Grid Plugin”插件可以识别的格式,并通过“Json”对象将数据发送到 Web 浏览器。
“SortIQueryable
”方法是一个辅助方法,用于对学生列表进行排序。我的“LoadjqData
”方法的实现基于学生存储在内存中且没有数据“索引”。如果您的数据存储在数据库中且数据索引良好,则不需要以相同的方式实现它。您可以利用数据库中的索引来提高速度。在实践中,虽然不总是如此,但从索引良好的数据库检索数据可能比操作 Web 服务器内存中缓存的数据更快。
运行应用程序
现在我们完成了功能最少的网格的实现,让我们看看它在 Web 浏览器中的外观。您可以在 Visual Studio 中调试运行此示例。当应用程序启动时,网格将显示在浏览器中。默认情况下,网格按“Id
”列升序排序。

如果您单击“Id
”列的标题,您会看到排序顺序已更改,并且具有最大“Id
”号的学生显示在顶部。

为了给“CodeProject”节省一些空间,我不会在此处发布测试此网格的所有图片。但如果您自己运行该应用程序,您可以测试此示例中实现的所有排序、分页和搜索功能。
关注点
- 这是文章的第一部分,演示了如何使用“jQuery Grid Plugin”插件。
- 读完本文后,您应该知道使用“jQuery Grid Plugin”插件创建基本网格所需的 JavaScript 库、CSS 样式和图片的最小集合。您还应该知道如何使用“MVC”控制器为网格实现基本的排序、分页和搜索功能。
- “jQuery Grid Plugin”插件是一个非常灵活和强大的 JavaScript 库,您可以在其上创建复杂的网格。本文仅展示了如何创建一个非常简单的网格来帮助您入门。
- 我希望您喜欢我的文章,希望本文能以某种方式帮助您。
历史
- 首次修订 - 2011 年 7 月 29 日