我正在使用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; }
}
答案 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>
)