根据勾选的复选框设置剃刀视图变量

时间:2017-09-11 10:39:16

标签: c# asp.net-mvc razor checkbox

我正在使用ASP.NET MVC在线库。 这是我的图书馆管理页面的视图模型:

public class ManageViewModel
{
    public IPagedList<ManageBookViewModel> WholeInventory;
    public IPagedList<ManageBookViewModel> CurrentInventory;
    public bool OldInventoryIsShown { get; set; } = false;
}

在相应的视图中,我有一个复选框,显示是否显示旧广告资源和本地变量modelList,如果选中该复选框,我想将其设置为Model.WholeInventory并{ {1}}否则。我使用Model.CurrentInventory来显示包含所有书籍的表格,每当我(取消)选中复选框以便正确显示列表时,我都需要重置其值。 这可能吗?我该怎么做呢?

在我看来,我目前有:

modelList

控制器操作:

<label class="switch">
    <input id="OldInventoryIsShown" name="OldInventoryIsShown" type="checkbox" />
    <span class="slider round"></span>
</label>
@{
    var modelList = Model.OldInventoryIsShown ? Model.WholeInventory : Model.CurrentInventory;
}      
@using (Html.BeginForm())
{
    <table id="bookInventory" class="table table-hover">
        <thead>
            <tr>
                <th>Author</th>
                <th>Title</th>
                ....
            </tr>
        </thead>
        @foreach (var entry in modelList)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => entry.Author)</td>
                <td>@Html.DisplayFor(modelItem => entry.Title)</td>
                ....
            </tr>
        }
    </table>

    <p>Page @(modelList.PageCount < modelList.PageNumber ? 0 : modelList.PageNumber) of @modelList.PageCount</p>    
    @Html.PagedListPager(modelList, page => Url.Action("Manage",  page }))
}

型号:

Book.cs

public ActionResult Manage(int? page)
{
    var wholeInventory = _bookService.GetBooksIncludingDisabled().Select(b => Mapper.Map<Book, ManageBookViewModel>(b));
    var currentInventory = _bookService.GetBooks().Select(b => Mapper.Map<Book, ManageBookViewModel>(b));
    int pageSize = 3;
    int pageNumber = page ?? 1;
    var model = new ManageViewModel
    {
        WholeInventory = wholeInventory.ToPagedList(pageNumber, pageSize),
        CurrentInventory = currentInventory.ToPagedList(pageNumber, pageSize)
    };
    return View(model);
}

ManageBookViewModel.cs

public class Book
{
    public int BookId { get; set; }
    [Required]
    [MinLength(1)]
    public string Title { get; set; }
    [Required]
    [MinLength(1)]
    public string Author { get; set; }
    ....
    public bool IsDisabled { get; set; } = false;
    public virtual ICollection<UserBook> UserBooks { get; set; }
}

1 个答案:

答案 0 :(得分:2)

您的ManageViewModel只需要为分页列表添加一个属性,它应该是IPagedList<Book>(请参阅下面的说明)

public class ManageViewModel
{
    public IPagedList<Book> Inventory;
    [Display(Name = "Include old inventory")]
    public bool OldInventoryIsShown { get; set; }
    ... // any other search/filter properties
}

并且您的视图需要在<form>元素中包含复选框,并且表单应该对您的控制器方法进行GET。然后,您还需要在OldInventoryIsShown方法中包含当前值@Html.PagedListPager()作为路由值,以便在分页时保留当前过滤器。

@model ManageViewModel
...
@using (Html.BeginForm("Manage", "ControllerName", FormMethod.Get))
{
    @Html.CheckBoxFor(m => m.OldInventoryIsShown)
    @Html.LabelFor(m => m.OldInventoryIsShown)
    ... // any other search/filter properties
    <input type="submit" value="search" />
}
<table id="bookInventory" class="table table-hover">
    ....
</table>
<p>Page @(modelList.PageCount < modelList.PageNumber ? 0 : modelList.PageNumber) of @modelList.PageCount</p>
@Html.PagedListPager(modelList, page => 
    Url.Action("Manage", new { page = page, oldInventoryIsShown = Model.OldInventoryIsShown })) // plus any other search/filter properties

最后在控制器方法中,您需要一个bool属性值的参数,并根据该值修改您的查询。

public ActionResult Manage(int? page, bool oldInventoryIsShown)
{
    int pageSize = 3;
    int pageNumber = page ?? 1;
    IQueryable<Book> inventory = db.Books;
    if (!oldInventoryIsShown)
    {
        inventory = inventory.Where(x => !x.IsDisabled);
    }
    ManageViewModel model = new ManageViewModel
    {
        Inventory = inventory.ToPagedList(pageNumber, pageSize),
        OldInventoryIsShown = oldInventoryIsShown
    };
    return View(model);
}

您当前的控制器代码非常低效。让我们假设您的表有10,000 Book条记录,其中5,000条已被“禁用”(已存档)。您当前的代码首先获取所有10,0000条记录并将它们添加到内存中。然后将所有映射到视图模型。然后,您调用另一个查询来获取另外5,0000条记录(这些记录只是您已有的记录的副本),您将这些记录添加到内存并映射到视图模型。但是你在视图中想要的只有3条记录(pageSize的值),所以你已经做了数千次额外的不必要的处理。

在您的情况下,不需要视图模型(尽管如果您确实需要一个,您将使用StaticPagedList方法 - 请参考this answer作为示例)。您的查询应使用您的数据库上下文生成IQueryable<Book>,以便只从数据库返回您需要的结果(ToPagedList()方法内部使用.Skip().Take() IQueryable<T>