zoukankan      html  css  js  c++  java
  • MVC项目实践,在三层架构下实现SportsStore-04,实现分页

    SportsStore是《精通ASP.NET MVC3框架(第三版)》中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器、URL优化、导航、分页、购物车、订单、产品管理、图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离。本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能。

    本篇为系列第四篇,包括:

    ■ 7、添加分页

      7、添加分页

    关于分页,是一系列的a标签,可以通过扩展HtmlHelper来实现。产生分页a标签的大致思路为:
    1、扩展方法需要遍历循环所有页数,而所有页数是由"总记录数/页容量",再经过计算得到。
    2、可以把总记录数、页容量、所有页数等封装成一个类提供给扩展方法。
    3、而包含总记录数、页容量、所有页数等这个类实例,当然是由控制器方法提供。

    创建PagingInfo来包装分页相关信息:

    using System;
    
    namespace MySportsStore.WebUI.Models
    {
        public class PagingInfo
        {
            public int TotalItems { get; set; }
            public int ItemsPerPage { get; set; }
            public int CurrentPage { get; set; }
    
            public int TotalPages
            {
                get { return (int)Math.Ceiling((decimal) TotalItems/ItemsPerPage); }
            }
        }
    }

    关于CurrentPage属性,扩展方法会根据它来确定是否要给a标签添加一个表示选中、当前页的css属性。

    扩展方法遍历循环所有页数,产生数字a标签,并根据PagingInfo的CurrentPage属性来判断是否要给a标签加上一个用来表示选中、当前页的属性:

    using System;
    using System.Text;
    using System.Web.Mvc;
    using MySportsStore.WebUI.Models;
    
    namespace MySportsStore.WebUI.HtmlHelpers
    {
        public static class PagingHelpers
        {
            public static MvcHtmlString PageLinks(this HtmlHelper html,
                PagingInfo pagingInfo,
                Func<int, string> pageUrl)
            {
                StringBuilder result = new StringBuilder();
                for (int i = 1; i <= pagingInfo.TotalPages; i++)
                {
                    TagBuilder tag = new TagBuilder("a");
                    tag.MergeAttribute("href", pageUrl(i));
                    tag.InnerHtml = i.ToString();
                    if (i == pagingInfo.CurrentPage)
                    {
                        tag.AddCssClass("selected");
                    }
                    result.Append(tag.ToString());
                }
                return MvcHtmlString.Create(result.ToString());
            }
        }
    }

    以上的pageUrl是一个委托,输入页面,输出一个包含查询字符串的URL。

    而添加的扩展方法需要在Views文件夹下的Web.config中注册后,才能在视图页中使用:

    <system.web.webPages.razor>
        <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <pages pageBaseType="System.Web.Mvc.WebViewPage">
          <namespaces>
              ......
            <add namespace="MySportsStore.WebUI.HtmlHelpers" />
          </namespaces>
        </pages>
      </system.web.webPages.razor>

    当然,分页是有关Product的分页,在显示Product列表的视图页上,除了分页,还有一个Product的集合,于是,我们可以把分页和Product的集合整合成一个视图模型:

    using System.Collections.Generic;
    using MySportsStore.Model;
    
    namespace MySportsStore.WebUI.Models
    {
        public class ProductsListViewModel
        {
            public IEnumerable<Product>  Products { get; set; }
            public PagingInfo PagingInfo { get; set; }
        }
    }

    Product控制器的List方法职责很明确:就是根据前台视图传递过来表示当前页的page变量,产生一个ProductsListViewModel的实例,传递给前台视图:

    using System.Web.Mvc;
    using MySportsStore.IBLL;
    using MySportsStore.WebUI.Models;
    using Ninject;
    
    namespace MySportsStore.WebUI.Controllers
    {
        public class ProductController : BaseController
        {
            [Inject]
            public IProductService ProductService { get; set; }
    
            public ProductController()
            {
                this.AddDisposableObject(ProductService);
            }
    
            public int PageSize = 4;
            public ViewResult List(int page = 1)
            {
                int totalCount = 0;
                ProductsListViewModel viewModel = new ProductsListViewModel()
                {
                    Products = ProductService.LoadPageEntities(p => true, p => p.Id, PageSize, page, out  totalCount, true),
                    PagingInfo = new PagingInfo(){CurrentPage = page, ItemsPerPage = PageSize, TotalItems = ProductService.Count(p => true)}
                };
                return View(viewModel);
            }
    
        }
    }

    Product/List.cshtml强类型视图:

    @model MySportsStore.WebUI.Models.ProductsListViewModel
    
    @{
        ViewBag.Title = "List";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    @foreach (var item in Model.Products)
    {
        <div class="item">
            <h3>@item.Name</h3>
            @item.Description
            <h4>@item.Price.ToString("c")</h4>
        </div>
    }
    
    <div class="pager">
        @Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
    </div>

    运行,得到如下结果:

    10

    让人欣慰的是:对Prouct列表进行了分页处理。稍有不足的是:页面链接以http://localhost/?page2这种形式存在。我们在路由设置中设置如下路由:

    routes.MapRoute(
                    null,
                    "Page{page}",
                    new {controller = "Product", action = "List"}
                );
    
                routes.MapRoute(
                    name: "Default",
                    url: "{controller}/{action}/{id}",
                    defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
                );

    运行,得到如下结果:

    11

    在Views/Shared/_Layout.chstml中布局页面,设置CSS,呈现如下页面:

    12

    在Product/List.cshtml视图页中,还可以把显示产品的逻辑放到一个部分视图中,以便重复利用。在Views/Shared下创建ProductSummary.cshtml强类型部分视图:

    @model MySportsStore.Model.Product
    
    <div class="item">
        <h3>@Model.Name</h3>
        @Model.Description
        <h4>@Model.Price.ToString("c")</h4>
    </div>

    最后,在Product/List.cshtml视图页中,在遍历Product集合的时候,加载部分视图:

    @model MySportsStore.WebUI.Models.ProductsListViewModel
    
    @{
        ViewBag.Title = "List";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    @foreach (var item in Model.Products)
    {
       Html.RenderPartial("PrductSummary", item);
    }
    
    <div class="pager">
        @Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
    </div>

    至此,完成分页。

    源码在这里

    “MVC项目实践,在三层架构下实现SportsStore”系列包括:

    MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构

    MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等

    MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层

    MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等

    MVC项目实践,在三层架构下实现SportsStore-04,实现分页

    MVC项目实践,在三层架构下实现SportsStore-05,实现导航

    MVC项目实践,在三层架构下实现SportsStore-06,实现购物车

    MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交

    MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器

    MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务

    MVC项目实践,在三层架构下实现SportsStore-10,连接字符串的加密和解密

    MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查

  • 相关阅读:
    在github上搭建hexo博客
    Docker镜像命令笔记
    Scrapy学习1:安装
    Android安全初学笔记
    Python数据结构01 线性结构
    IOS开发之__bridge,__bridge_transfer和__bridge_retained (转)
    设置字体样式 TTF
    NYTimes Objective-C 编程风格指南
    MQTT简介
    如何将自己编写的app放到真机上运行
  • 原文地址:https://www.cnblogs.com/darrenji/p/3811548.html
Copyright © 2011-2022 走看看