C# 根据选中的复选框设置razor视图变量

C# 根据选中的复选框设置razor视图变量,c#,asp.net-mvc,razor,checkbox,C#,Asp.net Mvc,Razor,Checkbox,我正在使用ASP.NETMVC开发一个在线库。 这是“库管理”页面的“我的视图”模型: public class ManageViewModel { public IPagedList<ManageBookViewModel> WholeInventory; public IPagedList<ManageBookViewModel> CurrentInventory; public bool OldInventoryIsShown { get;

我正在使用ASP.NETMVC开发一个在线库。 这是“库管理”页面的“我的视图”模型:

public class ManageViewModel
{
    public IPagedList<ManageBookViewModel> WholeInventory;
    public IPagedList<ManageBookViewModel> CurrentInventory;
    public bool OldInventoryIsShown { get; set; } = false;
}
控制器操作:

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);
}

您的
ManageViewModel
只需要为分页列表包含一个属性,它应该是
IPagedList
(请参见下面的说明)

最后,在controller方法中,您需要一个参数作为
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);
}
公共行动结果管理(int?页,bool oldInventoryShown)
{
int pageSize=3;
int pageNumber=第1页;
IQueryable inventory=db.Books;
如果(!OldInventoryShown)
{
库存=库存。其中(x=>!x.IsDisabled);
}
ManageViewModel模型=新的ManageViewModel
{
Inventory=Inventory.ToPagedList(页码、页面大小),
OldInventoryShown=OldInventoryShown
};
返回视图(模型);
}
您当前的控制器代码效率极低。假设您的表有10000条
Book
记录,其中5000条记录被“禁用”(存档)。您当前的代码首先获取所有100000条记录并将它们添加到内存中。然后将所有对象映射到视图模型。然后调用另一个查询以获取另外50000条记录(这些记录只是已有记录的副本),并将其添加到内存中并映射到视图模型。但是,视图中只需要3条记录(pageSize的值为
pageSize
),因此您已经进行了数千次额外的不必要处理


在您的情况下,不需要视图模型(尽管如果确实需要视图模型,可以使用
StaticPagedList
方法-请参阅示例)。您的查询应该使用数据库上下文生成
IQueryable
,以便只从数据库返回您需要的结果(在内部
ToPagedList()
方法使用
.Skip()
.Take()
on
IQueryable

为什么有2个
IPagedList
属性?由于您需要在服务器中填充此属性,因此您只需要一个属性(并根据
oldInventoryShown
)共享视图中的所有相关部分。不清楚您使用的是什么
modelList
for@StephenMuecke嗨,起初我有其他关于如何显示图书目录的计划,只有两个列表。现在我已经添加了OldInventoryShown,但是我不确定在模型中使用这个属性还是仅仅使用ViewBag属性或其他类型的变量是一个好主意。。。整个库存包括当前和旧库存。但您应该只有一个集合属性。这与使用
PagedList
进行的任何其他筛选没有什么不同-您有一个
,其中包括您
@Html.CheckBoxFor()
,并使其进入控制器方法,您可以根据复选框的值设置
IPagedList Inventory
的值(您需要在路由参数中包含
oldInventoryShown
的值,以便在视图中分页时保留该值)您还需要显示控制器方法。您好。谢谢您的回答。我实际上希望旧库存过滤器与搜索分开(在选中/取消选中方框时,应使用/移除过滤器,无需按下按钮)。这可能吗?我尝试了几件事,但没有成功。例如:在表单外部提取复选框,在包含搜索的表单中添加id,在javascript表单上单击名为submit的复选框。当然可以,但在这种情况下,您需要javascript来处理
。单击()
复选框的事件。但这不是正常的预期行为(以及糟糕的UI),因此最好只单击一个链接(根据当前显示的内容,您将显示(比如)“全部显示”或“仅显示当前”链接)该链接将调用相同的
Manage
method我通过添加一个submit类型的输入并隐藏类和一个id,并在每次单击复选框时触发一个单击事件来实现它。最初,我为表单添加了一个id并调用了submit,但这不起作用。我仍然无法使用e滑块样式,但我已经为此添加了另一个问题。谢谢:)您并不真正需要隐藏的输入。您可以使用
$('#yourCheckBoxId')。单击(function(){$(this).closest('form').submit();})但是,在一个表单元素上触发一个提交被认为是不好的实践,我本来可以没有隐藏字段。我可以把ID添加到我已经存在的搜索按钮中,虽然你的方法更优雅,我想我之所以坚持把复选框设计成一个滑动条,是因为我希望正确的AF发生一些事情。ter打开滑块,而不是传统的复选框。但我会记住您的建议,以备将来使用。这只是一个培训项目,因此我尝试以适合我的方式构建它。可能会将其部署到Azure,并在完成后提交给一些可用性测试:)
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; }
}
public class ManageBookViewModel
{
    public int BookId { get; set; }
    [Required(AllowEmptyStrings = false, ErrorMessage = "Enter the book title")]
    public string Title { get; set; }
    [Required(AllowEmptyStrings = false, ErrorMessage = "Enter the book author.")]
    public string Author { get; set; }
    ....
    public bool IsDisabled { get; set; }
}
public class ManageViewModel
{
    public IPagedList<Book> Inventory;
    [Display(Name = "Include old inventory")]
    public bool OldInventoryIsShown { get; set; }
    ... // any other search/filter properties
}
@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
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);
}