学习ASP.NET Core Razor 编程系列十九——分页

学习ASP.NET Core Razor 编程系列目录html

学习ASP.NET Core Razor 编程系列一数据库

学习ASP.NET Core Razor 编程系列二——添加一个实体编程

 学习ASP.NET Core Razor 编程系列三——建立数据表及建立项目基本页面浏览器

学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面并发

学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面async

学习ASP.NET Core Razor 编程系列六——数据库初始化post

学习ASP.NET Core Razor 编程系列七——修改列表页面学习

学习ASP.NET Core Razor 编程系列八——并发处理spa

学习ASP.NET Core Razor 编程系列九——增长查询功能3d

 学习ASP.NET Core Razor 编程系列十——添加新字段

学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库

学习ASP.NET Core Razor 编程系列十二——在页面中增长校验

学习ASP.NET Core Razor 编程系列十三——文件上传功能(一)

学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)

学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)

学习ASP.NET Core Razor 编程系列十六——排序

 学习ASP.NET Core Razor 编程系列十七——分组

学习ASP.NET Core Razor 编程系列十八——并发解决方案

 

    经过前面的教程学习,你能够实现一个简单的书籍管理系统。 在本教程将向书籍索引页中添加分页功能。

    1、向书籍列表页添加分页功能

    为了向书籍列表页添加分页功能,你须要安装X.PagedList.Core.Mvc

    首先,咱们须要安装分页组件包,在Visual Studio 2017中点击【项目】-【管理NuGet程序包】,打开NuGet包管理器窗体。

     其次,在NuGet包管理器窗体中,选择“浏览”标签,而后搜索X.PagedList,以下图所示。点击“安装”按钮安装X.PagedList.Core.Mvc的最新版本(本文中安装的版本为7.5.0)。

    第三, Nuget会下载X.PagedList.Mvc.Core包,并会弹出一个“更改”对话框,点击“肯定”按钮。

     第四,在把PagedList.Mvc安装完成以后,PagedList包也被安装上了。以下图。

        把PagedList.Mvc安装完成以后,第一件事就是对OnGetAsync方法作更多的修改并将分页按钮添加到Index视图中。 以下图所示添加了分页按钮的书籍列表页。

 

    2、向书籍列表后台代码添加分页功能

      在Pages/Books/Index.cshtml.cs中,用如下代码替换。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorMvcBooks.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
using X.PagedList; 

namespace RazorMvcBooks.Pages.Books
{
    public class IndexModel : PageModel
    {
        private readonly RazorMvcBooks.Models.BookContext _context; 

        public IndexModel(RazorMvcBooks.Models.BookContext context)
        {
            _context = context;
        }
 

        public List<Book> Books;
        public SelectList Publishs;
        public string Publish { get; set; }
        public string NameSort { get; set; }
        public string DateSort { get; set; }
        public string CurrentFilter { get; set; }
        public string CurrentSort { get; set; } 

        public X.PagedList.IPagedList<Book> Book { get;set; } 

        public async Task OnGetAsync(string publish, string searchString,string sortOrder,int? pageIndex)
        {

            ViewData["CurrentSort"] = sortOrder;
            Publish = publish;
            int pageSize = 5;
            ViewData["SearchString"] = searchString;
            var page = pageIndex ?? 1; 

            //查询
            IQueryable<string> PublishingQuery = from m in _context.Book
                                             orderby m.Publishing
                                             select m.Publishing;
 
            var books = from m in _context.Book
                         select m;
 

            if (!String.IsNullOrEmpty(searchString))
            {
                books = books.Where(s => s.Name.Contains(searchString));
            } 

            if (!String.IsNullOrEmpty(publish))
            {
                books = books.Where(x => x.Publishing == publish);
            }
            Publishs = new SelectList(await PublishingQuery.Distinct().ToListAsync()); 

            //排序
            NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
            DateSort = sortOrder == "Date" ? "date_desc" : "Date"; 

            ViewData["NameSortParm"] = NameSort;
            ViewData["DateSortParm"] = DateSort; 
 

            switch (sortOrder)
            {

                case "name_desc":
                    books = books.OrderByDescending(s => s.Name);
                    break;

                case "Date":
                    books = books.OrderBy(s => s.ReleaseDate);
                    break;

                case "date_desc":
                    books = books.OrderByDescending(s => s.ReleaseDate);

                    break;

                default:
                    books = books.OrderBy(s => s.Name);
                    break;

            }

            Book = await books.AsNoTracking().ToPagedListAsync(page, pageSize);
            //将分页结果放入ViewData供View使用
            ViewData["books"] = Book; 

        }
    }
}

 

      代码中将总页数参数、 当前的排序顺序参数和当前的筛选器参数添加到方法签名中。

        public async Task OnGetAsync(string publish, string searchString,string sortOrder,int? pageIndex)

       第一次显示页面,或若是用户未单击分页或排序连接,则全部参数都为null。 若是单击分页连接,页面变量将包含要显示的页码。

      名为 CurrentSort 的ViewData元素提供了当前已排序的试图,由于这必须包含在分页连接中以保持排序顺序在分页时相同。

      名为 searchString的ViewData元素提供了当前已筛选的视图。为了在分页过程当中维护筛选规则以及在页面从新显示的时候把筛选值恢复到文本框中,该值必定要被包含进分页连接里

      若是分页期间更改搜索字符串,显示的页会被重置为 1,由于新的筛选器可能会致使显示不一样的数据。 在文本框中输入了值以及按下提交按钮搜索字符串就会改变。 在这种状况下,searchString参数不为 null。

       在OnGetAsync方法的结尾,ToPagedListAsync方法将书籍查询结果转换为支持分页的集合类型,集合中包含了恰好能放进单页的书籍实体。 而后将这个单页大小的书籍集合 传递给视图。

            Book = await books.AsNoTracking().ToPagedListAsync(page, pageSize);

    代码中的ToPagedListAsync方法得到页面数和当前页码,并对IQueryable执行语句。 当IQueryable调用ToPagedListAsync时,该方法将返回只包含在请求页里的书籍列表。 属性HasPreviousPage和HasNextPage可用来启用或禁用PreviousNext分页按钮。

      Book属性咱们变动为

     public X.PagedList.IPagedList<Book> Book { get;set; }

 

      3、向书籍列表视图添加分页连接

      在Pages/Books/Index.cshtml中,用如下代码替换现有代码。 高亮代码为更改的代码。

@page
@model RazorMvcBooks.Pages.Books.IndexModel
@using X.PagedList.Mvc.Core;
@using X.PagedList.Mvc.Common;
@using X.PagedList;
<!--// 7.6及以上版本须要引入Common命名空间,以支持PagedListRenderOptions .7.5如下的版本则不须要。--> 

@{
    ViewData["Title"] = "Index";
} 

<h2>Index</h2> 
<p>
    <a asp-page="Create">Create New</a>
</p>

<form>
    <p>
        <select asp-for="Publish" asp-items="Model.Publishs">
            <option value="">All</option>
        </select>
        书籍名称
        <input type="text" name="SearchString">
        <input type="submit" value="查询" />
    </p>
</form> 

<table class="table">
    <thead>
        <tr>
            <th>
                <a asp-page="./Index" asp-route-sortOrder="@Model.NameSort">
                    @Html.DisplayNameFor(model => model.Book[0].Name)
                </a> 

            </th>
            <th>
                <a asp-page="./Index" asp-route-sortOrder="@Model.DateSort">
                    @Html.DisplayNameFor(model => model.Book[0].ReleaseDate)
                </a>

            </th>
            <th>
                @Html.DisplayNameFor(model => model.Book[0].Author)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Book[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Book[0].Publishing)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Book)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ReleaseDate)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Author)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Price)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Publishing)
                </td>
                <td>
                    <a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
                    <a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
                    <a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
                </td>
            </tr>
        }

    </tbody>
    <tfoot>
        <tr>
            <td class="text-muted" colspan="4">
                每页 @Model.Book.PageSize 条记录,本页有 @Model.Book.Count 条记录,共有 @Model.Book.TotalItemCount 条记录。
第 @(Model.Book.PageCount
< Model.Book.PageNumber ? 0 : Model.Book.PageNumber) 页,共 @Model.Book.PageCount 页。 @*这个条件表达式的目的是防止出现 记录为0的状况,会出现 总页数为0,而当前是第1页的状况。*@ </td> </tr> </tfoot> </table> @{ var prevDisabled = !Model.Book.HasPreviousPage ? "disabled" : ""; var nextDisabled = !Model.Book.HasNextPage ? "disabled" : ""; } <a asp-action="./Index" asp-route-publish="@Model.Publish" asp-route-sortOrder="@ViewData["CurrentSort"]" asp-route-pageIndex="@(Model.Book.PageNumber - 1)" asp-route-searchString="@ViewData["SearchString"]" class="btn btn-default @prevDisabled"> 上一页 </a> <a asp-action="./Index" asp-route-publish="@Model.Publish" asp-route-sortOrder="@ViewData["CurrentSort"]" asp-route-pageIndex="@(Model.Book.PageNumber + 1)" asp-route-searchString="@ViewData["SearchString"]" class="btn btn-default @nextDisabled"> 下一页 </a>


    其中经过标记帮助程序显示分页按钮:

<a asp-action="./Index"
 asp-route-publish="@Model.Publish"
   asp-route-sortOrder="@ViewData["CurrentSort"]"
   asp-route-pageIndex="@(Model.Book.PageNumber - 1)"
   asp-route-searchString="@ViewData["SearchString"]"
   class="btn btn-default @prevDisabled">
    上一页
</a>

    咱们在Visual Studio 2017中按F5运行应用,并在浏览器中浏览书籍列表页。以下图。

 

      在浏览器中单击以确保分页工做原理的不一样的排序顺序中的分页连接。 而后输入搜索字符串,而后重试以验证分页还适用正确使用排序和筛选的分页。

    4、向书籍列表视图添加分页连接

      虽然上面咱们实现了分页功能,可是通常分页,须要有页面显示,以下图。

       如何实现上图中的分页样式呢?在Pages/Books/Index.cshtml把书籍列表视图中“</table>”后面的代码,用如下代码替换,就能够实现。

@Html.PagedListPager(Model.Book, pageIndex => Url.Action("Index", new { pageIndex, sortOrder = ViewData["CurrentSort"], 
searchString = ViewData["SearchString"], pageSize = ViewData["PageSize"] }),
new PagedListRenderOptions { LinkToFirstPageFormat = "首页", LinkToNextPageFormat = "下一页", LinkToPreviousPageFormat = "上一页",
LinkToLastPageFormat = "末页", MaximumPageNumbersToDisplay = 5, DisplayItemSliceAndTotal = false })

    咱们在Visual Studio 2017中按F5运行应用,并在浏览器中浏览书籍列表页。使用鼠标单击页码“4”,咱们能够验证分页功能的正确使用。以下图。

   

相关文章
相关标签/搜索