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


    议题

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

    解决方案

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

    讨论

    添加筛选链接,需要修改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
    }
    &nbsp; | &nbsp;
    @if (ViewBag.CurrentFilter != "NewReleases")
    {
    @Html.ActionLink("New Releases", "Index", new {
    filter = "NewReleases", sortOrder =
    ViewBag.CurrentSortOrder })
    }
    else
    {
    @:New Releases
    }
    &nbsp; | &nbsp;
    @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("&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()方法进行修改。接受一个新的筛选器变量,根据用户选择的筛选器,将会减少书籍列表的数量。有以下两种实现方式:

    1. 为Linq添加Where的字符串选择条件;
    2. 使用标准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天发布的书籍,又或者用户也可以选择即将发布并搜索返回任何今天出版的书籍。否则,没有选择任何筛选器就会返回所有书籍。

    参考

    原书地址 书籍源代码

  • 相关阅读:
    LeetCode #53 Maximum Subarray 最大子数组 分治 线性DP
    POJ #2726 Holiday Hotel 快排
    《算法导论》第四章 练习题 Exercise
    POJ #1579 Function Run Fun 记忆化搜索
    《算法导论》第三章 练习题 Exercise
    《算法导论》 第二章 练习题 Exercise
    C语言数据类型
    codeblocks常用快捷键
    java 构造函数
    参考文献标注
  • 原文地址:https://www.cnblogs.com/o2ds/p/2287413.html
Copyright © 2020-2023  润新知