2015-10-04 127 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的答案。 –