使用PagedLive进阶说明
前一段时间我根据书中的内容,写了一篇入门级的ASP.NET MVC 分页制作博客《ASP.NET MVC:排序、搜索、分页以及多对多数据库》,里面就有描述到通过PagedLive对数据进行分页,但里面的代码只可以在小网站中应用,在项目实际应用的时候,如果数据库过大的时候,这种完全没有优化过的代码会使网站反应过慢。
在这篇文章里面会继续使用PagedLive这个工具,内容包括:对ASP.NET MVC的路由设置,使用PagedLive中的StaticPagedList,PagedLive一些自定义模板,这些都是我在实际的项目中应用到的,代码进行简化、加工、提纯,但保证一定可以运行。(如何安装PagedLive请参考文章:ASP.NET MVC:排序、搜索、分页以及多对多数据库)
首先来说明一下,假设我这个项目是用在一个News数据库的List页面,控制器取名为NewsController,页面是默认的Index,那么需要做如下设置:
1.打开App_Start文件夹,点击RouteConfig.cs,增加以下代码:
routes.MapRoute(
name: "Default2",
url: "News/Index/{page}",
defaults: new { controller = "News", action = "Index", page = 1 }
);
如果不做路由设置,那么该页面的网站是:http://www.xxx.com/News?page=2 或者是 http://www.xxx.com/News/Index?page=2 (根据系统路由的默认设置,这两者都是可以的)。
设置路由以后,运行页面,http://www.xxx.com/News/Index/2(News控制器如果没有其它页面,甚至可以把Index也给去掉。)
2.打开控制器NewsController,修改Index
using PagedList;
....
public ActionResult Index(int? page)
{
int pageSize = 10;
int pageIndex = page ?? 1;
int totalCount = 0;
var newslist = GetNews(pageIndex, pageSize, ref totalCount);
var NEWSlistpage = new StaticPagedList<News>(newslist, pageIndex, pageSize, totalCount);
return View(NEWSlistpage);
}
public List<News> GetNews(int pageIndex,int pageSize,ref int totalCount)
{
var newslist = (from p in db.News orderby p.NewsID descending select p).Skip((pageIndex - 1) * pageSize).Take(pageSize);
totalCount = db.News.Count();
return newslist.ToList();
}
从代码中,我们可以看出,我们首先提取出每一页需要的数据,采用Skip和Take进行数据提取,再进行ToList,最后把数据注入到StaticPagedList<News>中,一切就完成了,等着视图把它渲染出来。
3.视图的必要代码如下:
@using PagedList;
@using PagedList.Mvc;
@model PagedList.StaticPagedList<xxx.Models.News>
......
@section AddToHead{
<link href="@Url.Content("~/Content/PagedList.css")" rel="stylesheet" type="text/css" />
}
.....
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Subtitle)
</td>
<td>
@Html.DisplayFor(modelItem => item.date)
</td>
<td>
@Html.ActionLink("编辑新闻", "EditNews", new { id = item.NewsID }) |
@Html.ActionLink("删除新闻", "DeleteNews", new { id = item.NewsID })
</td>
</tr>
}
</tbody>
</table>
@Html.PagedListPager(Model, page => Url.Action("Index", new { page =page }), new PagedListRenderOptions { LinkToFirstPageFormat = "<< 第一页", LinkToPreviousPageFormat = "< 上一页", LinkToNextPageFormat = "下一页 >", LinkToLastPageFormat = "最末页 >>" })
</div>
上面视图的代码只是显示必要代码,但是总体的思路已经出来了,引用PagedList.css,数据怎么显示等等,最后通过@Html.PagedListPager
将分页的模板给显示出来。运行结果如下图。使用PagedLive,分页就是这么简单!
最后,关于分页样式模板--例如,要不要显示最前页最后页、如何显示等,参考下面的示例。有时间,不妨将所有的代码都运行一遍,下次在设计的时候就心里有底了。
<h2>Out-of-the-box Pager Configurations</h2>
<h3>Default Paging Control</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }))
<h3>Minimal Paging Control</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), PagedListRenderOptions.Minimal)
<h3>Minimal Paging Control w/ Page Count Text</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), PagedListRenderOptions.MinimalWithPageCountText)
<h3>Minimal Paging Control w/ Item Count Text</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), PagedListRenderOptions.MinimalWithItemCountText)
<h3>Page Numbers Only</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), PagedListRenderOptions.PageNumbersOnly)
<h3>Only Show Five Pages At A Time</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), PagedListRenderOptions.OnlyShowFivePagesAtATime)
<!-- ---------------------------------------- -->
<h2>Custom Pager Configurations</h2>
<h3>Custom Wording (<em>Spanish Translation Example</em>)</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), new PagedListRenderOptions { LinkToFirstPageFormat = "<< Primera", LinkToPreviousPageFormat = "< Anterior", LinkToNextPageFormat = "Siguiente >", LinkToLastPageFormat = "Ultima >>" })
<h3>Show Range of Items For Each Page</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), new PagedListRenderOptions { FunctionToDisplayEachPageNumber = page => ((page - 1) * ViewBag.Names.PageSize + 1).ToString() + "-" + (((page - 1) * ViewBag.Names.PageSize) + ViewBag.Names.PageSize).ToString(), MaximumPageNumbersToDisplay = 5 })
<h3>With Delimiter</h3>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Index", new { page = page }), new PagedListRenderOptions { DelimiterBetweenPageNumbers = "|" })