2015-10-04 70 views
0

我有这个复选框,它的工作原理......但每次表单提交复选框都会被取消选中。你不会相信我已经花在论坛上的时间和沮丧,而Google只是看着所有的答案,但我需要这个看似简单的问题。早上浪费了。如何保留MVC /剃须刀中复选框的状态?

这里就是该复选框在我看来显示出来:

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

} 

也没什么可说在我的模型的复选框,因为据推测,将其布尔添加到表中的所有条目。对不起,我是新手。

+0

相反,使用Viewbag来保存检查的数据,这样你就不必将它包含在模型中,如果你正在为你的模型使用'IEnumreable ',如果bool在模型的实例中,使用'Model [特定模型类的索引] .IsChecked.' – mahlatse

+0

同时,我设法通过ViewBag方法(这不是我在我的教程中学习的东西)勉强找到一些功能,但我仍然希望我能理解如何执行对的。 – Methodician

回答

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 
} 

注意:不要处理复选框点击事件!

和修改索引方法

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发布的价值观和返回过滤的结果的局部视图,然后更新当前页面,而这产生获得更好的性能每次都有新页面。

+0

不错!我认为这实际上会起作用。此外,新手,因为我是一个学习建立视图模型的机会!顺便解释一下。当我回家时我会尝试。 – Methodician

+0

真棒TY @Stephan Muecke!这是我正在寻找的。问题和评论... **问题:**你会说这是使用“强类型模型”作为其他人建议? **评论:**我必须采取一些额外的步骤,以便我编辑您的答案,如果它可以做得更好/不同,请随时重新编辑。 – Methodician

+0

我已拒绝您的修改。你提出的代码根本就没有必要。你只需要'@ Html.DisplayNameFor(m => m.Posts [0] .AuthorName)' - 即使集合中没有元素也可以工作 –

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) 
+0

我的确试图通过向我的模型添加一个bool来实现这一点,但它的行为很奇怪,要么是因为我没有得到它,要么是因为视图使用的是IEnumerable ,并且不知道如何处理整个表只有一次需要bool的条目。 – Methodician

+1

我还发现@ Html.CheckBoxFor(m => m.IsChecked)是不可接受的。它可以正常工作@ Html.DIsplayFor和其他助手,但CheckBoxFor不想采取模型属性...我做错了吗? – Methodician

+0

最后,为了清晰起见,我继续添加模型到OP。谢谢你的帮助! – Methodician

1

您使用的方法不好。 @PaRiMal Raj表示,强类型模型在MVC模式中更可取。当你是新的,我只是让答案更有条理。首先创建这样一个模型从表格数据发送到控制器:

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

希望这会有所帮助。

+0

_It让我感觉更接近一些,但我遇到了一些问题:_ ** 1)** CheckBoxFor仍然不想采用任何模型属性(尽管DisplayNameFor很容易识别它们)_AND_ ** 2)** views只能接受一个模型语句,所以我不清楚我是否应该有一个包含searchString和IsChecked属性的新模型(我称之为“BlogFilter”),并将其添加到我的BlogPost模型中一个属性本身,或者直接将这两个添加到BlogPost模型中...因为向视图添加第二个BlogFilter at-model语句会返回错误。 – Methodician

+0

我想我也不完全清楚我的模型如何不是“强类型” - 也许你可以指向我的资源,从中我可以更好地把握这意味着什么? – Methodician

+0

如果你已经有一个模型,然后创建一个合并前一个模型和新模型的视图模型。我的意思是它将满足您与控制器进行通信的要求。你可以看到@Stephen Muecke的答案。 –