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

Javascript 如何在MVC/razor中保留复选框的状态?,javascript,html,asp.net-mvc,razor,checkbox,Javascript,Html,Asp.net Mvc,Razor,Checkbox,我有这个复选框,它的工作。。。但是每次表单提交时,复选框都会被取消选中。你不会相信我花在论坛和谷歌上的时间和挫败感,除了这个看似简单的问题的答案之外。浪费了一个上午 以下是复选框在我的视图中显示的位置: @using (Html.BeginForm()) { <p> Search Criteria: @Html.TextBox("searchString") <br /> <input type="submit" value="Filter" /&g

我有这个复选框,它的工作。。。但是每次表单提交时,复选框都会被取消选中。你不会相信我花在论坛和谷歌上的时间和挫败感,除了这个看似简单的问题的答案之外。浪费了一个上午

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

@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 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添加到表中的所有条目中。对不起,我对这一切都不熟悉。

我建议您使用强类型模型,这会使事情变得更简单

你的模型应该是

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)

您使用的方法不好strong类型模式在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 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; }
}

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

我确实尝试通过向模型中添加bool来实现这一点,但它的行为异常,或者是因为我没有得到它,或者因为视图使用的是IEnumerable,并且不知道如何处理整张包含bool的条目表,bool只需要一次。我还发现@Html.CheckBoxFor(m=>m.IsChecked)是不可接受的。它可以与@Html.DIsplayFor和其他帮助程序配合使用,但CheckBoxFor不希望获取模型属性。。。我做错了吗?最后,为了清晰起见,我把我的模型添加到OP中。谢谢你的帮助!而是使用一个Viewbag来保存选中的数据,这样您就不必将其包含在模型中,如果您正在为您的模型使用
IEnumreable
,如果bool在模型的实例中,则使用
model[特定模型类的索引].IsChecked.
与此同时,我通过使用ViewBag方法(这不是我在教程中学习到的东西)成功地欺骗了一些功能但我仍然希望我能理解如何正确操作。这让我感觉有点接近,但我有两个问题:1)CheckBoxFor仍然不想获取任何模型属性(尽管DisplayNameFor很容易识别它们),2)视图只能接受一个at模型语句,所以我不清楚是否应该有一个新模型(我称之为“BlogFilter”),它包含一个searchString和IsChecked属性,并将其作为属性本身添加到我的BlogPost模型中,或者直接将这两个属性添加到BlogPost模型中……因为在视图中添加第二个BlogFilter at model语句会返回一个错误。我想我也不完全清楚我的模型如何不是“强类型”的-也许你可以给我指一个资源,我可以从中更好地理解这意味着什么?如果你已经有一个模型,那么创建一个viewmodel合并以前的模型和新模型。我的意思是,这将满足你与控制器通信的要求。你可以看到@Stephen Muecke的答案。很好!我认为这确实有效。另外,虽然我是新手,但这是一个学习构建视图模型的机会!顺便说一句,解释得很好。我回家后会试试。太棒了,TY@Stephan Muecke!这就是我要找的。问题和评论……问题:你说这是使用“强类型模型”吗正如其他人所建议的那样?评论:我必须采取一些额外的步骤,以便编辑您的答案,如果可以做得更好/不同,请随意重新编辑。我拒绝了您的编辑。您建议的代码根本不是必需的。您只需要
@Html.DisplayNameFor(m=>m.Posts[0].AuthorName)
-即使集合中没有元素,它也会起作用。因此,如果希望
bool
是可选的,正确的方法是使用
bool?includeUserPostsOnly
(即可为空),然后可以使用
if(includeUserPostsOnly.HasValue&&includeUserPostsOnly.Value)检查
我想有一个更好的方法,就是让它工作。谢谢你的更新。我会用它简化我的代码!
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);
}
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; }
}
@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
}
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 );
}