您的位置:首页 > 编程语言 > ASP

[翻译]ASP.NET MVC 3 开发的20个秘诀(九)[20 Recipes for Programming MVC 3]:对列表进行筛选

2011-12-14 12:33 686 查看
[b]议题[/b]

当排序和分页不能帮助用户找到他们需要的结果,那就根据条件筛选内容的方式来帮助他们寻找。

[b]解决方案[/b]

添加一个新的链接可以让用户选择预制的标准内容通过Linq Library对列表内容进行数据筛选。

[b]讨论[/b]

添加筛选链接,需要修改Books视图、Index视图和BookController控制器。修改与前两个秘诀类似,添加HTML链接,内容必须是允许用户选择的内容。添加三个新链接:全部、新发布和即将发布。新发布的内容是最近两周发布的内容。即将发布的内容是预告未来发布的内容。

下面是新的Books和Index视图。三个链接中都会包含排序规则的参数(以便保持当前用户的排序选项),后两个链接会包含一个名为“filter”的新的变量参数。与分页链接类似,激活的筛选器只显示链接,未激活的显示文字链接,以标识用户当前选定的筛选器选项。为了在用户更改排序选项时也能保持当前筛选器的选项,也需要按照当前筛选器更新:

@model PagedList.IPagedList<MvcApplication4.Models.Book>

<h2>@MvcApplication4.Resources.Resource1.BookIndexTitle</h2>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<p>
Show:
@if (ViewBag.CurrentFilter != "")
{
@Html.ActionLink("All", "Index", new {
sortOrder = ViewBag.CurrentSortOrder })
}
else
{
@:All
}
  |  
@if (ViewBag.CurrentFilter != "NewReleases")
{
@Html.ActionLink("New Releases", "Index", new {
filter = "NewReleases", sortOrder =
ViewBag.CurrentSortOrder })
}
else
{
@:New Releases
}
  |  
@if (ViewBag.CurrentFilter != "ComingSoon")
{
@Html.ActionLink("Coming Soon", "Index", new {
filter = "ComingSoon", sortOrder =
ViewBag.CurrentSortOrder })
}
else
{
@:Coming Soon
}
</p>
@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")


在之前我们创建的分页链接的分部视图中,也需要做这样的修改。在下面的代码中,四个分页链接中也需要传送当前页码、排序规则和筛选器选项:

<p>
@if (Model.HasPreviousPage)
{
@Html.ActionLink("<< First", "Index", new {
page = 1,
sortOrder = ViewBag.CurrentSortOrder,
filter = ViewBag.CurrentFilter })

@Html.Raw(" ");

@Html.ActionLink("< Prev", "Index", new {
page = Model.PageNumber - 1,
sortOrder = ViewBag.CurrentSortOrder,
filter = ViewBag.CurrentFilter })
}
else
{
@:<< First
@Html.Raw(" ");
@:< Prev
}
  
@if (Model.HasNextPage)
{
@Html.ActionLink("Next >", "Index", new {
page = Model.PageNumber + 1,
sortOrder = ViewBag.CurrentSortOrder,
filter = ViewBag.CurrentFilter })

@Html.Raw(" ");

@Html.ActionLink("Last >>", "Index", new {
page = Model.PageCount,
sortOrder = ViewBag.CurrentSortOrder,
filter = ViewBag.CurrentFilter })
}
else
{
@:Next >
@Html.Raw(" ")
@:Last >>
}
</p>


接下来,再对BooksController中的Index()方法进行修改。接受一个新的筛选器变量,根据用户选择的筛选器,将会减少书籍列表的数量。有以下两种实现方式:

为Linq添加Where的字符串选择条件;

使用标准Linq的强类型选择条件。

由于通常筛选器通常不会包含太多条目,所以在这个秘诀中我们将使用第二种方法。使用第二种方法的时候,因为条目是预制的且是强类型的并不是动态的,所以不需要额外的输入检查或SQL注入防治。

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 MvcApplication4.Models;
using MvcApplication4.Utils;
using PagedList;

namespace MvcApplication4.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);
int maxRecords = 1;
int currentPage = page - 1;
return View(books.ToPagedList(currentPage,
maxRecords));
}
...
}

}


在上面的例子中,用户可以筛选最新的内容并搜索返回今天或过去14天发布的书籍,又或者用户也可以选择即将发布并搜索返回任何今天出版的书籍。否则,没有选择任何筛选器就会返回所有书籍。

[b]参考[/b]

原书地址 书籍源代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐