(9)在结果中筛选

问题

当排序和分页都不够帮用户去找到他们想要的结果时,另外一种帮助用户找到他们想要的结果的方式是根据特殊的规则过滤。

解决方案

添加新的links 允许使用预先的条件去过滤并且使用LINQ类库去在数据中过滤。    

讨论

为了添加过滤的链接,需要在Book/Index view 和BookController中做改变。

改变的View和前两个秘方差不多。需要添加HTML去允许用户去选择他们想如何过滤内容。三个连接将被添加:全部的,新发布的和即将到来的。新发布的将被定义为最近2周发布的。即将到来的就被定义为还没发布的。

下边是新的 Book/Index view。有三个link。第一个link包含当前的sortOrder,剩下的2个link包含了新的变量filter。像分页link一样。如果当前的filter是你选中的话,把他显示成静态文本而不是link,其他的fitler设置为link的形式。确保用户更改排序规则时,filter也被维护。我们的Index view 要更新成如下:

双击代码全选
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
75
76
77
78
79
80
@Html.Partial("_Paging")
< table >
     < tr >
         < th >
             @Html.ActionLink("Title", "Index", new
        {
            sortOrder = ViewBag.TitleSortParam,
            filter = ViewBag.CurrentFilter
        })
         </ th >
         < th >
             @Html.ActionLink("Isbn", "Index", new
        {
            sortOrder = ViewBag.IsbnSortParam,
            filter = ViewBag.CurrentFilter
        })
         </ th >
         < th >
             Summary
         </ th >
         < th >
             @Html.ActionLink("Author", "Index", new
        {
            sortOrder = ViewBag.AuthorSortParam,
            filter = ViewBag.CurrentFilter
        })
         </ th >
         < th >
             Thumbnail
         </ th >
         < th >
             @Html.ActionLink("Price", "Index", new
        {
            sortOrder = ViewBag.PriceSortParam,
            filter = ViewBag.CurrentFilter
        })
         </ th >
         < th >
             @Html.ActionLink("Published", "Index", new
        {
            sortOrder = ViewBag.PublishedSortParam,
            filter = ViewBag.CurrentFilter
        })
         </ th >
         < th >
         </ th >
     </ tr >
     @foreach (var item in Model)
     {
         < tr >
             < td >
                 @Html.DisplayFor(modelItem => item.Title)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Isbn)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Summary)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Author)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Thumbnail)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Price)
             </ td >
             < td >
                 @Html.DisplayFor(modelItem => item.Published)
             </ td >
             < td >
                 @Html.ActionLink("Edit","Edit", new { id = item.ID }) |
                 @Html.ActionLink("Details","Details", new { id = item.ID }) |
                 @Html.ActionLink("Delete","Delete", new { id = item.ID })
             </ td >
         </ tr >
     }
</ table >
@Html.Partial("_Paging")
 

上一个秘方中创建的_Paging的Partial view也需要被更新。在下边的例子里,4个paging link 已经被更新成传递了当前的filter,page,和sortOrder。以下是_Paging更新后的代码:

双击代码全选
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
< p >
     @if (Model.HasPreviousPage)
     {
         @Html.ActionLink("<< First ", "Index", new
{
     page = 1 ,
     sortOrder = ViewBag .CurrentSortOrder,
     filter = ViewBag .CurrentFilter
})
         @Html.Raw("&nbsp;");
         @Html.ActionLink("< Prev", "Index", new
{
     page = Model .PageNumber - 1,
     sortOrder = ViewBag .CurrentSortOrder,
     filter = ViewBag .CurrentFilter
})
     }
     else
     {
         @:<< First
         @Html.Raw("&nbsp;");
         @:< Prev
     }
     &nbsp;&nbsp;
     @if (Model.HasNextPage)
     {
         @Html.ActionLink("Next >", "Index", new
{
     page = Model.PageNumber + 1,
     sortOrder = ViewBag.CurrentSortOrder,
     filter = ViewBag.CurrentFilter
})
         @Html.Raw("&nbsp;");
         @Html.ActionLink("Last >>", "Index", new
{
     page = Model.PageCount,
     sortOrder = ViewBag.CurrentSortOrder,
     filter = ViewBag.CurrentFilter
})
     }
     else
     {
         @:Next >
         @Html.Raw("&nbsp;")
         @:Last >>
     }
</ p >
 

接下来我们要改变BooksController,在Index()Action 中更改代码。新接收一个filter变量。图书的列表将基于用户选择的filter选项被缩减。有2中方法实现filter。

  1. 再次使用动态Linq库 的where子句。
  2. 使用标准的Linq 和一个switch块去创建一个强类型的子句。

由于传统的filter link并不包含太多的条目,这个秘方,我们选择用第二种实现方法。这样做的好处是,我们不需要考虑SQL注入的问题,因为他是强类型的,并且不是动态的。

以下是BooksController部分代码:

 

双击代码全选
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
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;
using MvcApplication.Models;
using MvcApplication.Utils;
using PagedList;
namespace MvcApplication.Controllers
{
     public class BooksController : Controller
     {
         private BookDBContext db = new BookDBContext();
         //
         // GET: /Books/
         public ViewResult Index(string sortOrder,string filter, int page = 1)
         {
             #region ViewBag Resources
 
             #endregion
             #region ViewBag Sort Params
             #endregion
             var books = from b in db.Books select b;
             #region Filter Switch
             switch (filter)
             {
                 case "NewReleases":
                     var startDate = DateTime.Today.AddDays(-14);
                     books = books.Where(b => b.Published
                     <= DateTime.Today.Date
                     && b.Published >= startDate
                     );
                     break;
                 case "ComingSoon":
                     books = books.Where(b => b.Published >
                     DateTime.Today.Date);
                     break;
                 default:
                     // No filter needed
                     break;
             }
             ViewBag.CurrentFilter =
             String.IsNullOrEmpty(filter) ? "" : filter;
             #endregion
             books = books.OrderBy(sortOrder);
             const int maxRecords = 2;
             var currentPage = page <= 0 ? 1 : page;
             return View(books.ToPagedList(currentPage,maxRecords));
         }
     }
}
 

在上边的例子里,如果用户选择NewReleases 这个filter,这个搜索将返回今天或者14天之内出版的书。或者用户选择了Coming soon,搜索将返回即将出版的书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lin&Yi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值