视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MVC5 + EF6 + Bootstrap3 (11) 实现排序、搜索、分页
2020-11-27 22:36:10 责编:小采
文档


前言

本节我们向这个页面中加入排序、搜索和分页功能。

排序

从上图中的地址栏中可以看到这个页面调用的是Company Controller下的Index Action.因此我们就先打开Controllers文件夹下的CompanyController.cs文件,写入如下代码:

using System.Linq;
using System.Web.Mvc;
using SlarkInc.DAL;
using System;

namespace SlarkInc.Controllers
{
 public class CompanyController : Controller
 {
 private CompanyContext db = new CompanyContext();
 public ViewResult Index(string sortOrder)
 {
 ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
 ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
 var workers = from w in db.Workers
 select w;
 switch (sortOrder)
 {
 case "first_desc":
 workers = workers.OrderByDescending(w => w.FirstName);
 break;
 case "last_desc":
 workers = workers.OrderByDescending(w => w.LastName);
 break;
 case "last":
 workers = workers.OrderBy(w => w.LastName);
 break;
 default:
 workers = workers.OrderBy(w => w.FirstName);
 break;
 }
 return View(workers.ToList());
 }
 }
}

第11行,Index Action 的参数sortOrder用来传递给Controller排序的信息。sortOrder有4个可能值。这4个值体现在17到31行的switch..case语句中。如果是first_desc则对FirstName用OrderByDescending倒序排列。如果是last_desc则对LastName倒序排列。如果是last则对LastName用OrderBy函数顺序排列。如果是空则对FirstName顺序排列。第13-14行用Viewbag存储当前排列的相反排列字符串,用于在View中生成链接。第15-16行,用Linq to Entity 从数据库中选取要排序的数据。第32行将排序好的数据以List的形式传递给View。

在对应的View文件~\Views\Company\Index.cshtml中,修改其表头部分,代码如下。

<tr>
 <th>
 @Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FirstNameSortParm })
 </th>
 <th>
 @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LastNameSortParm })
 </th>
 <th>@Html.DisplayNameFor(model => model.Sex)</th>
 <th>@Html.DisplayNameFor(model => model.Rating)</th>
</tr>

黄色的部分为修改后的代码。我们把以前纯文本的表头改成一个超链接,链接的参数从ViewBag中获得。点击链接可以获得与当前排序相反的排序效果。

 通过浏览器查看此页面。之后点击LastName链接,则按照上面代码会生成如下页面:

 

参数sortOrder为last则这个表按lastName顺序排列。

搜索

一般查询页面都会有搜索功能帮助我们查看自己想要的页面。下面我们就来实现这个功能。

还是从Controller开始,Index Action的代码写成如下形式:

public ViewResult Index(string sortOrder, string searchString)
{
 ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
 ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
 var workers = from w in db.Workers
 select w;
 if (!string.IsNullOrEmpty(searchString))
 {
 workers = workers.Where(w => w.FirstName.Contains(searchString)
 || w.LastName.Contains(searchString));
 }
 switch (sortOrder)
 {
 case "first_desc":
 workers = workers.OrderByDescending(w => w.FirstName);
 break;
 case "last_desc":
 workers = workers.OrderByDescending(w => w.LastName);
 break;
 case "last":
 workers = workers.OrderBy(w => w.LastName);
 break;
 default:
 workers = workers.OrderBy(w => w.FirstName);
 break;
 }
 return View(workers.ToList());
}

上面代码中黄色的部分就是我们所添加的。第1行,searchString向Controller传递用来搜索的字符串。第7行,字符串不为空时执行搜索。这里的搜索用到了Linq里的Where函数,它通过一个Lambda表达式来筛选出符合条件的数据。这个条件就是9-10行的"或"连接的两个Contains函数。Contains函数表示其所属字符串是否包含其参数字符串。整个筛选条件表示返回所有FisrtName或LastName包含筛选字符串的记录。

 下面看~\Views\Company\Index.cshtml的改动:

@using(Html.BeginForm())
{
 <p>
 Find by name: @Html.TextBox("SearchString","", new { @class = "form-control", @Style = "display:inline" })
 @Html.Submit("Submit")
 </p>
}

在table的上面加入这些代码,它是一个Form,包含一个输入框和提交按钮,这个Form会把输入框中的搜索字符串提交给当前Controller完成搜索操作。其中的输入框,加入了class和style对其进行了Bootstrap美化。

通过浏览器查看这个页面,在搜索框中输入b并且提交,之后会出现如下页面:

可以看到搜索结果是FirstName或LastName包含b(不分大小写),的所有记录。

分页

数据查询免不了要分页。这里我们用一个名为PagedList的插件来实现这个功能。

如下所示,在菜单栏里选择工具->库程序包管理->程序包管理控制台。

之后会在Visual Studio窗口的下面看到一个程序包管理控制台窗口。在其中输入Install-Package PagedList.Mvc。PagedList就会自动安装到项目中。窗口如下所示。

Paged List 安装好后,我们就开始修改代码,从Controller开始:

using System.Linq;
using System.Web.Mvc;
using SlarkInc.DAL;
using System;
using PagedList;

namespace SlarkInc.Controllers
{
 public class CompanyController : Controller
 {
 private CompanyContext db = new CompanyContext();
 public ViewResult Index(string sortOrder, string searchString, string currentFilter, int? page)
 {
 ViewBag.CurrentSort = sortOrder;
 ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
 ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
 if(searchString != null)
 {
 page = 1;
 }
 else
 {
 searchString = currentFilter;
 }
 ViewBag.CurrentFilter = searchString;

 var workers = from w in db.Workers
 select w;
 if (!string.IsNullOrEmpty(searchString))
 {
 workers = workers.Where(w => w.FirstName.Contains(searchString)
 || w.LastName.Contains(searchString));
 }
 switch (sortOrder)
 {
 case "first_desc":
 workers = workers.OrderByDescending(w => w.FirstName);
 break;
 case "last_desc":
 workers = workers.OrderByDescending(w => w.LastName);
 break;
 case "last":
 workers = workers.OrderBy(w => w.LastName);
 break;
 default:
 workers = workers.OrderBy(w => w.FirstName);
 break;
 }
 int pageSize = 3;
 int pageNumber = (page ?? 1);
 return View(workers.ToPagedList(pageNumber,pageSize));
 }
 }
}

 黄色标记的为需要改动的部分。第5行,需要引用PagedList。第12行currentFilter参数用来在翻页时保持搜索字符串不丢失。第17到25行的作用是,当有一个新的字符串要搜索,那么翻当前页就自动变成第一页,否则,当前页不变。第49-51行设置每页3条数据,设置页数,并将数据以List的形式发送个View。其中(page ?? 1)的意思是如果page为null则给page赋值为1否则,page不为null那么该是多少就是多少。所以能让默认页为1.

 @model PagedList.IPagedList<SlarkInc.Models.Worker>
@using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" />
 <br />
 @using(Html.BeginForm("Index","Company",FormMethod.Get))
 {
 <p>
 Find by name: @Html.TextBox("SearchString",ViewBag.CurrentFilter as string, new { @class = "form-control", @Style = "display:inline" })
 @Html.Submit("Submit")
 </p>
 }
<table class="table">
 <tr>
 <th>
 @Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FirstNameSortParm })
 </th>
 <th>
 @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LastNameSortParm })
 </th>
 <th>Sex</th>
 <th>Rating</th>
 </tr>
 @foreach (var item in Model)
 {
 <tr>
 <td>
 @Html.DisplayFor(modelItem => item.FirstName)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.LastName)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.Sex)
 </td>
 <td>
 @Html.DisplayFor(modelItem => item.Rating)
 </td>
 </tr>
 }
</table>
<br/>
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, page => Url.Action("Index",
 new {page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter}))

第1行定义了PagedList 类型的model。第2行引用PagedList。第3行,引入,PagedList相关的css文件,这个文件在安装插件的时候会自动保存到项目里。第5行BeginForm函数的参数有变化,其生成的Form会使用Get方法。Get方法会在url里显示提交的参数,这样可以通过url来记录查询参数,方便通过复制url给他人来展现自己的查询结果。第42行用于显示第几页,共几页。第43-44行,用于生成每一页的按钮。

运行此页面,当页面出来时点击页面下方的"2"按钮转到第2页。生成的页面如下所示:

可以看到页面下方的分页按钮和页数统计,美观大方。

结尾

下载本文
显示全文
专题