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