1、引言

  在MVC开发中我们经常会对数据进行分页的展示。通过分页我们可以从服务端获取指定的数据来进行展示。这样既节约了数据库查询的时间也节约了网络传输的数据量。在MVC开发中使用的比较多的应该是MVCPager控件。这个控件提供无刷新分页等功能。虽然我们有这么好的控件可以使用,但是我们还是需要通过简单的例子来看一下原始的分页技术的雏形,学习下原始分页的技术实现。

2、简单的分页实现

  此处使用T_Products表查询商品数据,然后进行展示。商品类定义如下:

1
2
3
4
5
6
7
8
9
public sealed class Product
    {
        public string ProductId { getset; }
        public string ProductName { getset; }
        public string ProductImage { getset; }
        public int Price { getset; }
        public string CategoryId { getset; }
        public string Description { getset; }
    }

  我们通过仓储模式来定义数据的存储操作。其接口定义和实现类定义

1
2
3
4
5
6
7
8
public interface IProductRepository
    {
        /// <summary>
        /// 获取数据库中全部的商品信息
        /// </summary>
        /// <returns></returns>
        IQueryable<T_Product> GetAll(int pageIndex, int pageSize, out int total);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ProductRepository : IProductRepository
    {
        private DB_ShoppingEntities shoppingEntities = null;
 
        public ProductRepository()
        {
            this.shoppingEntities = new DB_ShoppingEntities();
        }
 
 
        public IQueryable<T_Product> GetAll(int pageIndex, int pageSize, out int total)
        {
            total = this.shoppingEntities.T_Product.Count();
            return this.shoppingEntities.T_Product.AsQueryable().OrderBy(p => p.Price).Skip((pageIndex - 1) * pageSize).Take(pageSize);
        }
    }

  通过上面的代码我们清晰的看到我们通过Linq表达式来获取指定页数的数据,当然也获取了当前操作所获取的数据的条数。下面我们需要定义自定义分页帮助类来协助我们构造分页所需的一些信息。定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
    /// 分页帮助类
    /// </summary>
    public sealed class MyPager
    {
        private int total;
        //当前页的索引
        public int pageIndex { getset; }
        //总的页数
        public int pageCount { getset; }
 
        public MyPager(int total, int pageSize, int pageIndex)
        {
            this.total = total;
            this.pageIndex = pageIndex;
            //计算总页数
            int result = this.total % pageSize;
            this.pageCount = result == 0 ? this.total / pageSize : this.total / pageSize + 1;
        }
    }

  我们可以想一想分页的基本流程。我们客户端发送请求到服务端获取指定的数据。这时候我们将符合条件的数据查询出来以后,返回给客户端即可。但是分页的页码也是需要更新的。这里我们可以将分页的一些信息也一起返回给客户端。然客户端在展示新的数据的同时也更新分页的状态。在这里我们可以将分页的信息封装到一个类里面。这样我们可以重新定义一个类模型将需要返回给客户端的Products和分页信息封装到一起一起发给客户端,这样客户端就可以进行渲染。

1
2
3
4
5
6
7
8
/// <summary>
    /// 带分页功能的产品类别
    /// </summary>
    public sealed class PagedProducts
    {
        public IList<Product> Products { getset; }
        public MyPager pager { getset; }
    }

  这时我们来看控制器中的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ProductController : Controller
    {
        private IProductRepository productRepository = null;
 
        //每一页展示的数量
        private const int pageSize = 4;
 
        public ProductController(IProductRepository productRepository)
        {
            this.productRepository = productRepository;
        }
 
 
        public ViewResult Index(int pageIndex = 1)
        {
            PagedProducts pagedProducts = null;
            IList<Product> list = null;
            int total = 0;
            var products = this.productRepository.GetAll(pageIndex, pageSize, out total);
            if (products != null && products.Count() > 0)
            {
                pagedProducts = new PagedProducts();
                list = new List<Product>();
                foreach (var item in products)
                {
                    list.Add(new Product
                    {
                        ProductId = item.ProductID,
                        ProductName = item.ProductName,
                        ProductImage = item.ProductImage == null "" : item.ProductImage,
                        Price = (int)item.Price,
                        CategoryId = item.CategoryID,
                        Description = item.Description
                    });
                }
                //定义分页对象
                pagedProducts.Products = list;
                pagedProducts.pager = new MyPager(total, pageSize, pageIndex);
            }
            return View(pagedProducts);
        }
    }

  我们定义的pagedProducts包含了Products和pager对象。这样我们在客户端就可以进行渲染。客户端的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@model Shopping.Models.PagedProducts
@using Shopping.ExtendMethod;
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<style type="text/css">
    table {
        width:60%;
        height:auto;
        margin:60px auto;
        border-collapse:collapse;
        border:0px;
    }
    table tr{
        text-align:center;
        height:30px;
        line-height:30px;
    }
    /*设置第一行的样式*/
    table tr:first-child {
        
        font-weight:bold;
    }
 
    table tr td {
        border:1px #565252 solid;
    }
    div {
        width:60%;
        height:30px;
        margin:20px auto;
    }
    div a {
        line-height:30px;
        text-align:center;
        padding:12px;
        font-size:14px;
        text-decoration:none;
    }
    div .selected {
        font-weight:bold;
        font-size:16px;
    }
</style>
<table>
    @if (Model != null && Model.Products.Count > 0)
    {
        <tr>
            <td>编号</td>
            <td>名称</td>
            <td>价格</td>
        </tr>
        foreach (var item in Model.Products)
        {
            <tr>
                <td>@item.ProductId</td>
                <td>@item.ProductName</td>
                <td>@item.Price</td>
            </tr>
        }
    }
    else
    {
        <tr>
            <td>
                当前不存在数据
            </td>
        </tr>
    }
</table>
<!--分页-->
<div>
    @Html.MyPagerLink(Model.pager, index => Url.Action("Index", new { pageIndex = index }))
</div>

  我们看到MyPagerLink方法,这个方法就是我们自定义进行分页的渲染方法。通过服务端传递的分页信息来渲染指定的分页信息进行展示。其代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/// <summary>
    /// 定义扩展方法
    /// </summary>
    public static class ExtendMethod
    {
        /// <summary>
        /// 自定义分页扩展方法
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="pager">分页对象</param>
        /// <param name="pageUrl">定义委托,该委托满足给定int类型的参数返回string类型的返回结果</param>
        /// <returns></returns>
        public static MvcHtmlString MyPagerLink(this HtmlHelper htmlHelper, MyPager pager, Func<intstring> pageUrl)
        {
            StringBuilder result = null;
            if (pager.pageCount > 0)
            {
                result = new StringBuilder();
                for (int i = 1; i <= pager.pageCount; i++)
                {
                    TagBuilder tag = new TagBuilder("a");
                    //指定页数的链接
                    tag.MergeAttribute("href", pageUrl(i));
                    tag.InnerHtml = i.ToString();
                    if (i == pager.pageIndex)
                    {
                        tag.AddCssClass("selected");
                    }
                    result.Append(tag.ToString());
                }
            }
            return MvcHtmlString.Create(result == null "" : result.ToString());
        }
    }

  我们通过看代码可以发现改代码通过获取分页的总页数来动态的创建<a>标签。我们来看一下最后的效果:

 
分类: ASP.NET MVC

mvc自定义分页(加页数的)(转)的更多相关文章

  1. MVC自定义分页

    MVC自定义分页 之前我发表了一篇MVC无刷新分页的文章,里面用的是MvcPager控件,但是那个受那个控件限制,传值只能用PagedList,各方面都受到了限制,自由度不够高,现在还是做MVC无刷新 ...

  2. MVC自定义分页(附表跳转页Loading提示)

    之前我发表了一篇MVC无刷新分页的文章,里面用的是MvcPager控件,但是那个受那个控件限制,传值只能用PagedList,各方面都受到了限制,自由度不够高,现在还是做MVC无刷新分页,但是想直接用 ...

  3. Mvc自定义分页控件

    MVC开发分页常常使用第三方控件,生成的分页HTML带有版权申明,虽然免费,但是总有的别扭.于是,某日,楼主闲来蛋疼,折腾了个自定义分页控件: 先来展示下效果图: 1>当分页不超过10页的时候, ...

  4. ASP.NET MVC 数据分页

    作为一个菜鸟级的程序猿,总结一下学到的两种数据分页. 1.真分页 真分页就是需要时从数据库里读出需要多的数据,利用存储过程可实现.网上的分页SQL特别多,数据库自带的一些方法也可方便的帮助分页,但是我 ...

  5. ASP.NET MVC 数据分页思想及解决方案代码

    作为一个程序猿,数据分页是每个人都会遇到的问题.解决方案更是琳琅满目,花样百出.但基本的思想都是差不多的. 下面给大家分享一个简单的分页器,让初学者了解一下最简单的分页思想,以及在ASP.NET MV ...

  6. MVC下分页的自定义分页一种实现

    1.引言 在MVC开发中我们经常会对数据进行分页的展示.通过分页我们可以从服务端获取指定的数据来进行展示.这样既节约了数据库查询的时间也节约了网络传输的数据量.在MVC开发中使用的比较多的应该是MVC ...

  7. Django项目:CRM(客户关系管理系统)--21--13PerfectCRM实现King_admin分页页数

    {#table_data_list.html#} {## ————————08PerfectCRM实现King_admin显示注册表的字段表头————————#} {% extends 'king_m ...

  8. GridView自定义分页样式(上一页,下一页,到第几页)

    今天要为网站做一个文章列表,发现GridView的分页样式很难看,于是结合网上的例子,自己做了一个.不是很美观,不过还是很实用的,先看下效果吧,如图(1). 图(1)GridView分页效果 自定义G ...

  9. c-lodop获取任务页数-回调里给全局变量赋值并加减

    LODOP一个任务里可以自动分页,也可以手动分页,超文本会按照打印项高度或超过纸张会自动分页(相关博文:Lodop打印控件 超文本自动分页),如果是自动分页,是无法知道究竟分了多少页,整个任务打了多少 ...

随机推荐

  1. Angular组件——投影

    运行时动态改变组件模版的内容.没路由那么复杂,只是一段html,没有业务逻辑. ngContent指令将父组件模版上的任意片段投影到子组件上. 一.简单例子 1.子组件中使用<ng-conten ...

  2. 咸鱼入门到放弃4——Http协议

    一.什么是HTTP协议 HTTP是hypertext transfer protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的 ...

  3. POJ 1201 Intervals (经典) (差分约束)

    <题目链接> 题目大意:给你$n$段区间,$a_i,b_i,c_i$ 表示在 $[a_i,b_i]$ 区间内至少要选择$c_i$个点.现在问你在满足这n个条件的情况下,最少要选多少个点? ...

  4. python class属性

    代码一: class A(object): pass a = A() a.name = "class_A" print(a.name) #class_A 代码二:class A(o ...

  5. DWM1000 测距原理简单分析 之 SS-TWR

    蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛 正文: DWM1000 超宽带测距,使用的TOF(time of fly) 的方式,也就是计算无线电磁波传输时 ...

  6. 2017-2018 ACM-ICPC Pacific Northwest Regional Contest (Div. 1)

    A. Odd Palindrome 所有回文子串长度都是奇数等价于不存在长度为$2$的偶回文子串,即相邻两个字符都不同. #include<cstdio> #include<cstr ...

  7. ajax多图上传

    百度云代码 参考:https://segmentfault.com/q/1010000004218827

  8. MySQL数据库表损坏后的修复方法

    步骤:1.sql语句:check table tabTest; 如果出现的结果说Status是OK,则不用修复,如果有Error2.Linux执行: myisamchk -r -q /var/lib/ ...

  9. 对Spring 的RestTemplate进行包装

    Spring的RestTemplate及大地简化了REST Client的开发,但每次还要编写大量的模板代码,代码不够简洁.我对他进行了一次包装,采用接口来声明REST接口,使用Annotation对 ...

  10. 百度API获取经纬度使用

    首先通过百度地图,注册账号,然后申请密钥 http://lbsyun.baidu.com/apiconsole/key 搜索某个关键字 http://api.map.baidu.com/place/v ...