65.9K
CodeProject 正在变化。 阅读更多。
Home

在 MVC 中使用 jQuery Grid 插件的示例 - 第 1 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.70/5 (16投票s)

2011年7月29日

CPOL

7分钟阅读

viewsIcon

244249

downloadIcon

10381

本文提供了一个在 MVC 中使用 jQuery Grid 插件的简单示例。

引言

本文提供了一个在 MVC 中使用 jQuery Grid 插件的简单示例。

背景

这是文章的第一部分,演示了如何使用“jQuery Grid Plugin”插件。该示例将向您展示如何实现一个只读网格。本文试图回答以下问题:

  • 要使用“jQuery Grid Plugin”插件,需要下载的最少 JavaScript 库和 CSS 样式有哪些?
  • 如何实现一个基本的网格?
  • 如何为网格实现分页、排序和搜索功能?

jQuery Grid Plugin”插件使用“Ajax”调用从服务器获取数据进行显示。我们可以使用许多平台,例如“PHP”,来实现服务器代码来处理“Ajax”调用。在本例中,服务器代码是用 ASP.NET “MVC”控制器实现的。

本文假定您已经具备“jQuery”和“MVC”的一些基本知识。如果您对这些主题不熟悉,可以很容易地在互联网上找到参考资料。

Visual Studio 解决方案

SolutionExplorer.jpg

要使用“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”列升序排序。

RunAppStart.jpg

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

RunAppSorting.jpg

为了给“CodeProject”节省一些空间,我不会在此处发布测试此网格的所有图片。但如果您自己运行该应用程序,您可以测试此示例中实现的所有排序、分页和搜索功能。

关注点

  • 这是文章的第一部分,演示了如何使用“jQuery Grid Plugin”插件。
  • 读完本文后,您应该知道使用“jQuery Grid Plugin”插件创建基本网格所需的 JavaScript 库、CSS 样式和图片的最小集合。您还应该知道如何使用“MVC”控制器为网格实现基本的排序、分页和搜索功能。
  • jQuery Grid Plugin”插件是一个非常灵活和强大的 JavaScript 库,您可以在其上创建复杂的网格。本文仅展示了如何创建一个非常简单的网格来帮助您入门。
  • 我希望您喜欢我的文章,希望本文能以某种方式帮助您。

历史

  • 首次修订 - 2011 年 7 月 29 日
© . All rights reserved.