MVC無刷新分頁(即局部刷新,帶搜索,頁數選擇,排序功能)

  我查看了不少網站,大部分評論分頁都是局部刷新的,可大部分電商商品展現分頁都是有刷新頁面的,因而我便作了一個商品展現無刷新分頁的例子。接下來我就將作一個模仿淘寶已買到的寶貝功能,不過個人是無刷新分頁的。css

  至於爲什麼要用無刷新分頁(局部刷新)呢,我我的以爲有幾點緣由:jquery

  1. 提升用戶體驗,無刷新分頁網頁看起來相對靜止,滾輪不會跳到上面,加載速度比較快;

  2. 減輕網站服務器壓力,返回局部頁面(其中無需包含樣式和腳本)確定比返回整個頁面要來的輕鬆;

  3. 還有個分頁的好處就是減輕數據庫的壓力,返回幾行的數據確定比返回全部行的數據要輕鬆啦。

  首先右擊項目-管理NuGet程序包,聯機搜索MvcPager,並安裝web

  而後在BLL的訂單管理OrderManage類裏添加一個ToPagedList方法,第幾頁pageIndex和每頁行數pageSize是必需的,其餘均可空。ajax

 1         public PagedList<SH_Order> ToPagedList(int pageIndex, int pageSize, string orderBy, string orderName, SH_OrderState? state, SH_PayType? payType, DateTime? startTime, DateTime? endTime, long? accountId)
 2         {
 3             using (var db = new ShopContext())
 4             {
 5                 var log = db.Order.Include(s => s.Account);
 6 
 7                 if (accountId != null)
 8                 {
 9                     log = db.Order.Where(o => o.AccountId == accountId);
10                 }
11 
12                 if (state != null)
13                 {
14                     log = log.Where(o => o.State == state);
15                 }
16 
17                 if (payType != null)
18                 {
19                     log = log.Where(o => o.PayType == payType);
20                 }
21 
22                 if (startTime != null)
23                 {
24                     log = log.Where(o => o.LogTime > startTime);
25                 }
26 
27                 if (endTime != null)
28                 {
29                     log = log.Where(o => o.LogTime < endTime);
30                 }
31 
32                 if (!string.IsNullOrWhiteSpace(orderName))
33                 {
34                     log = log.Where(o => o.OrderName.Contains(orderName));
35                 }
36 
37                 switch (orderBy)
38                 {
39                     case "LogTime":
40                         log = log.OrderBy(o => o.LogTime);
41                         break;
42                     case "LogTime Desc":
43                         log = log.OrderByDescending(o => o.LogTime);
44                         break;
45                     case "AccountName":
46                         log = log.OrderBy(o => o.Account.AccountName);
47                         break;
48                     case "AccountName Desc":
49                         log = log.OrderByDescending(o => o.Account.AccountName);
50                         break;
51                     case "TotalPrice":
52                         log = log.OrderBy(o => o.TotalPrice);
53                         break;
54                     case "TotalPrice Desc":
55                         log = log.OrderByDescending(o => o.TotalPrice);
56                         break;
57                     case "OrderName":
58                         log = log.OrderBy(o => o.OrderName);
59                         break;
60                     case "OrderName Desc":
61                         log = log.OrderByDescending(o => o.OrderName);
62                         break;
63                     case "PayTime":
64                         log = log.OrderBy(o => o.PayTime);
65                         break;
66                     case "PayTime Desc":
67                         log = log.OrderByDescending(o => o.PayTime);
68                         break;
69                     default:
70                         log = log.OrderByDescending(o => o.ID);
71                         break;
72                 }
73 
74                 return log.AsNoTracking().ToPagedList(pageIndex, pageSize);
75             }
76         }

  但是隻有訂單還不行呀,訂單是有訂單明細的,也就是說除了訂單表還有訂單明細表,這個不搞出來豈不是作不了淘寶的那個功能?那就再加一個方法:數據庫

1         public List<List<SH_OrderDetail>> GetOrderDetailByOrders(IEnumerable<SH_Order> orders)
2         {
3             using (var db = new ShopContext())
4             {
5                 var details = new List<List<SH_OrderDetail>>();
6                 orders.ToList().ForEach(o => details.Add(db.OrderDetail.Include(j => j.Gift).Where(j => j.OrderId == o.ID).AsNoTracking().ToList()));
7                 return details;
8             }
9         }

  至此,訂單和訂單明細都能獲取,BLL的邏輯處理已經完成了。接下來就是Web項目的事了。先建一個訂單模型:服務器

1     public class OrdersViewModel
2     {
3         public PagedList<SH_Order> Orders { get; set; }
4 
5         public List<List<SH_OrderDetail>> OrderDetails { get; set; }
6     }

  這個模型用來存放從BLL獲取的訂單和訂單明細,而後就處理Controller了:mvc

        [ShopAuthorize]
        public ActionResult OrderList(string orderState, string orderBy, string payType, string logTime, string orderName, string giftName, int pageSize = 10, int pageIndex = 1)
        {
            DateTime? startTime = null;
            DateTime? endTime = null;

            switch (logTime)
            {
                case "1MonthAgo":
                    endTime = DateTime.Now.AddMonths(-1);
                    break;
                default:
                    startTime = DateTime.Now.AddMonths(-1);
                    break;
            }

            SH_OrderState enumOrderState;
            var result = Enum.TryParse(orderState, out enumOrderState);
            SH_OrderState? endOrderState = null;
            if (result) endOrderState = enumOrderState;

            SH_PayType enumPayType;
            result = Enum.TryParse(payType, out enumPayType);
            SH_PayType? endPayType = null;
            if (result) endPayType = enumPayType;

            var manage = new OrderManage();
            var orders = manage.ToPagedList(pageIndex, pageSize, orderBy, orderName, endOrderState, endPayType, startTime, endTime, long.Parse(User.Identity.GetUserId()));
            var orderList = new OrdersViewModel
            {
                Orders = orders,
                OrderDetails = manage.GetOrderDetailByOrders(orders)
            };

            if (Request.IsAjaxRequest())
            {
                return PartialView("_OrderList", orderList);
            }

            ViewBag.OrderState = Common.Common.GetSelectListByEnum(typeof(SH_OrderState), "所有訂單狀態");
            ViewBag.PayType = Common.Common.GetSelectListByEnum(typeof(SH_PayType), "所有支付方式");
            ViewData["GiftLevel"] = Common.Common.GetSelectListByEnum(typeof(SH_GiftLevel));
            return View("OrderManage", orderList);
        }

  其中ShopAuthorize是我自定義的登陸驗證:app

 1     public class ShopAuthorizeAttribute : AuthorizeAttribute
 2     {
 3         protected override bool AuthorizeCore(HttpContextBase httpContext)
 4         {
 5             var user = httpContext.User;
 6             return user != null && user.IsInRole("Account");
 7         }
 8         
 9         protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
10         {
11             if (filterContext == null)
12             {
13                 return;
14             }
15 
16             var path = filterContext.HttpContext.Request.Path;
17             const string strUrl = "/Account/Login?returnUrl={0}";
18             filterContext.HttpContext.Response.Redirect(string.Format(strUrl, HttpUtility.UrlEncode(path)), true);
19         }
20     }

  Controller也完成了數據的傳遞,最後只剩下頁面了,先說OrderManage頁面,此頁面關鍵地方在於異步提交的表單:異步

  提醒一下,要用Ajax提交需加上jquery.unobtrusive-ajax.min.js和@{ Html.RegisterMvcPagerScriptResource(); }引用,而且引用Jquery1.7以上版本,另外還需加上ide

  其中每頁行數選擇的就本身在OrderManage寫一個下拉列表,再寫個腳本實現改變行數時改變表單裏的id爲pageSize的值,並觸發表單的提交便可,排序的也同理改變表單裏的id爲orderBy的值並觸發表單的提交便可。最後就只剩下局部頁面_OrderList了,這裏的關鍵點在於:

  至此,無刷新分頁功能已完成,來張效果圖吧

  是否是和淘寶的有點像捏

  聲明,本文有參考http://www.webdiyer.com/mvcpager/,樣式也能夠在http://www.webdiyer.com/mvcpager/demo/applycss/學習一下。歡迎探討共同窗習喔。

相關文章
相關標籤/搜索