如何在MVC / razor中保留复选框的状态?

时间:2015-10-04 17:52:14

标签: javascript html asp.net-mvc razor checkbox

我有这个复选框,它可以工作......但每次表单提交复选框都会取消选中。你不会相信我在论坛上花费的时间和挫折感,而谷歌只关注这个看似简单问题所需的答案。浪费了早晨。

以下是我的视图中显示的复选框:

@using (Html.BeginForm())
{
    <p> Search Criteria: @Html.TextBox("searchString") <br />
    <input type="submit" value="Filter" /></p>
    <p>Show only my posts: <input type="checkbox" name="authorFilter" onchange="this.form.submit();"/></p>

}

这是控制器处理这些东西的地方:

public ActionResult Index(string searchString)
{
    var posts = from p in db.BlogPosts
                select p;

    var authorFilterCheck = Request.Form["authorFilter"];

    if (authorFilterCheck == "on")
    {
        string userID = User.Identity.GetUserId();
        posts = posts.Where(i => i.AuthorID.Equals(userID));
    }

    if (!string.IsNullOrEmpty(searchString))
        posts = posts.Where(
            x =>
                x.Body.Contains(searchString) ||
                x.Title.Contains(searchString));

    return View(posts);
}

因此,当它被选中时,它会添加一个过滤器并刷新页面。但是当它刷新时,复选框被取消选中(但过滤器仍然被应用),这样你就永远不能删除过滤器(加上空的复选框会误导用户认为没有过滤器)......

以下是需要的模型:

public class BlogPost
{
    [Key]
    public int PostID { get; set; }
    public string AuthorID { get; set; }
    public string Title { get; set; }
    public string Body { get; set; }

    [Display(Name = "Date Authored")]
    [DataType(DataType.DateTime)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public System.DateTime DateCreated { get; set; }

}

我的模型中没有关于复选框的内容,因为可能会将其bool添加到表中的所有条目。对不起,我对这一切都不熟悉。

3 个答案:

答案 0 :(得分:1)

你正在使用的方法并不好。 强类型模型在MVC模式中更受欢迎,因为@PaRiMal Raj说。因为你是新人,我只是让答案更有条理。首先像这样创建一个模型,将数据从表单发送到控制器:

public class Model
{
    [Required]
    public string searchString {get ; set;}
    public bool IsChecked {get ; set;}
}

现在更改查看代码,如下所示:

@using (Html.BeginForm())
{
   @Html.LabelFor(m => m.searchString)                    
   @Html.TextBoxFor(m => m.searchString)       
   <p>Show only my posts: </p>
   @Html.CheckBoxFor(m => m.IsChecked)
   <input type="submit" value="Filter" />
}

在控制器中:

public ActionResult Index(Model model)
{
    if (!ModelState.IsValid){
       return View(model);
     }
    var posts = from p in db.BlogPosts
            select p;   
    if (model.Ischecked)
    {
       string userID = User.Identity.GetUserId();
       posts = posts.Where(i => i.AuthorID.Equals(userID));
    }
  string searchString=model.searchString;
if (!string.IsNullOrEmpty(searchString))
    posts = posts.Where(
        x =>
            x.Body.Contains(searchString) ||
            x.Title.Contains(searchString));

 return View(posts);
}

希望这会有所帮助。

答案 1 :(得分:1)

使用表示您要显示/编辑的视图模型

public class BlogPostsVM
{
  [Display(Name = "Search Criteria")]
  public string SearchText { get; set; }
  [Display(Name = "Include my posts only")]
  public bool IncludeUserPostsOnly { get; set; }
  public IEnumerable<BlogPost> Posts { get; set; }
}

在视图中,将表单方法更改为GET并强烈绑定到模型

@model BlogPostsVM
@using (Html.BeginForm("Index", "yourControllerName", FormMethod.Get))
{
    @Html.LabelFor(m => m.SearchText)
    @Html.TextBoxFor(m => m.SearchText)
    @Html.LabelFor(m => m.IncludeUserPostsOnly)
    @Html.CheckBoxFor(m => m.IncludeUserPostsOnly)
    <input type="submit" value="Search" />
}

@foreach(var post in Model.Posts)
{
    // Display the blog posts
}

注意:请勿处理复选框点击事件!

并将Index方法修改为

public ActionResult Index(string searchText, bool includeUserPostsOnly)
{

    var posts = from p in db.BlogPosts select p;
    if (includeUserPostsOnly)
    {
        string userID = User.Identity.GetUserId();
        posts = posts.Where(i => i.AuthorID.Equals(userID));
    }
    if (!string.IsNullOrEmpty(searchText))
    {
        posts = posts.Where(x => x.Body.Contains(searchText) || x.Title.Contains(searchText));
    }
    BlogPostsVM model = new BlogPostsVM
    {
        SearchText = searchText,
        IncludeUserPostsOnly = includeUserPostsOnly,
        Posts = posts
    };
    return View(model );
}

附注:通过使用ajax发布值并返回已过滤结果的部分视图,然后更新当前页面而不是每次都生成新页面,您将获得更好的性能。

答案 2 :(得分:0)

我建议你使用强类型模型,它会让事情变得更容易

你的模型应该是

public class MyModel
{
    public book IsChecked {get ; set;}
}

使用此

public class StoreController : Controller
{
    [HttpPost]
    public ActionResult Index(MyModel model)
    {
        // here you will get if its checked or not
        return View(model); // it will preserve the state
    }

    [HttpGet]
    public ActionResult Index()
    {
      var model = new MyModel();
      model.IsChecked = false; // it is false by default anyways
      return View();
    }
}

以这种方式渲染下拉列表

@Html.CheckBoxFor(m => m.IsChecked)