问题描述
我有一个与作为搜索字段复选框,单选按钮和文本框的集合的形式MVC4页面。当后的选择进行分析和较低的结果网格与新成果更新。现在所有的表单值都在返回消灭了,新的结果显示在网格中 - 只有网格是模型的一部分。
I have a MVC4 page that has a form with a collection of checkboxes, radio buttons and textboxes used as the search fields. Upon post the selections are parsed and the lower results grid is updated with new results. Right now all the form values are wiped out upon return and the new results are displayed in the grid - only the grid is part of the model.
我希望所有的形式选择以邮寄后保留它们的值,使用户可以看到(和变化)的下一篇文章/搜索的选择。在窗体popuplated与viewbags。
I want all the form selections to retain their values after post so the user can see (and change) the selections for next post/search. The form is popuplated with viewbags.
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "searchform" }))
{
@Html.ValidationSummary("Please correct the following errors")
<div style="float:left;">
<div style="float:left;">
<label>Name:</label>
@Html.TextBox("name")
</div>
<div style="float:left; margin-left:15px">
<label>Company:</label>
@Html.TextBox("company")
</div>
<div style="float:left; margin-left:65px">
<label>Date Range:</label>
@Html.TextBox("dateStart", "", new { @class = "datefield", type = "date" })
to
@Html.TextBox("dateEnd", "", new { @class = "datefield", type = "date" })
</div>
</div>
<div style="clear: both;">
Match Any Categories? <input type="radio" name="categoryMatchAll" value="false" checked="checked" />
Match All Categories? <input type="radio" name="categoryMatchAll" value="true" />
</div>
<div style="float:left;">
<div id="searchform-categories" style="float:left;">
<div class="scroll_checkboxes">
<label>Categories</label>
<ul>
@foreach (var x in ViewBag.Categories)
{
<li>
<input type="checkbox" name="categories" value="@x.Id"/>
@x.Name
</li>
}
</ul>
</div>
</div>
<div id="searchform-diversity" style="float:left; margin-left:30px">
<div class="search-selection" style="float:left;">
<label>Minority Owned</label>
<ul>
@foreach (var x in ViewBag.Minorities)
{
<li>
@Html.RadioButton("minorities", (String)x.Id.ToString())
@x.Name
</li>
}
</ul>
</div>
<div class="search-selection" style="float:left;">
<label>Diversity Class</label>
<ul>
@foreach (var x in ViewBag.Classifications)
{
<li>
@Html.RadioButton("classifications", (String)x.Id.ToString())
@x.Name
</li>
}
</ul>
</div>
</div>
</div>
<div style="clear: both;">
<input type="submit" value="Search Profiles" />
<input type="submit" value="Reset" />
</div>
}
数据网格被绑定到模型
the data grid is bound to the model as
@model IEnumerable<VendorProfileIntranet.Models.VendorProfile>
<table id="VendorTable" width="100%" class="gradeA">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.CompanyName)
</th>
<th>
@Html.DisplayNameFor(model => model.City)
</th>
<th>
@Html.DisplayNameFor(model => model.State)
</th>
<th>
@Html.DisplayNameFor(model => model.DateCreated)
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td class="list-field">
@Html.DisplayFor(modelItem => item.Name)
</td>
<td class="list-field">
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td class="list-field">
@Html.DisplayFor(modelItem => item.City)
</td>
<td>
@Html.DisplayFor(modelItem => item.State)
</td>
<td class="list-field">
@Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td class="list-field">
@Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) |
@Html.ActionLink("View", "View", new { id = item.ProfileID }) |
@Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" })
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td> </td>
</tr>
</tfoot>
推荐答案
因此,这里是我通常如何解决这个问题。我的笔记纯属我看来(religous?)有关在MVC项目命名类,来保持清楚自己的目的。
So here is how I typically solve this problem. My notes are purely my opinion (religous?) about naming classes in an MVC project to keep clear their purpose.
接口夫妇以保持其可扩展的:
Couple of interfaces to keep it extensible:
// be specific about what type of results, both in the name of the
// interface and the property needed, you don't want to have overlapping
// properies on your classes, I like suffixing interfaces that are specific
// to a View or Partial View with View
public interface IPersonSearchResultsView
{
IEnumerable<EFPerson> PersonSearchResults { get; }
}
public interface IPersonSearchCriteriaView
{
PersonSearchCriteriaModel PersonSearchModel { get; }
}
班夫妇
// I like suffixing classes that I only use for MVC with Model
public PersonSearchCriteriaModel
{
public string Name {get; set;}
public string Company {get; set;}
public string DateStart {get; set;}
public string DateEnd {get; set;}
}
// I like suffixing classes that I used passed to a View/Partial View
// with ViewModel
public class PersonSearchViewModel : IPersonSearchResultsView,
IPersonSearchCriteriaView
{
public IEnumerable<EFPerson> PersonSearchResults { get; set; }
public PersonSearchCriteriaModel PersonSearchModel { get; set; }
}
现在你的控制器,我会在某种程度上,这也将让你做阿贾克斯在未来进行设置。
Now for your controllers, I'll set them up in a way that would also allow you to do Ajax in the future.
public PersonController : Controller
{
public ActionResult Search()
{
var model = new PersonSearchViewModel();
// make sure we don't get a null reference exceptions
model.PersonSearchModel = new PersonSearchCriteriaModel ();
model.PersonSearchResults = new List<EFPerson>();
return this.View(model);
}
[HttpPost]
public ActionResult Search(PersonSearchViewModel model)
{
model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel);
return this.View(model)
}
// You could use this for Ajax
public ActionResult Results(PersonSearchViewModel model)
{
model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel);
return this.Partial("Partial-SearchResults", model)
}
private GetPersonResults(PersonSearchCriteriaModel criteria)
{
return DbContext.GetPersonResults(criteria)
}
}
创建几个局部的意见的意见。
Create a couple of partial-views your Views.
/Views/Person/Partial-SearchCriteria.cshtml
@model IPersonSearchCriteriaView
// the new part is for htmlAttributes, used by Ajax later
@using (Html.BeginForm(..., new { id="searchCriteria" }))
{
// Here is were the magic is, if you use the @Html.*For(m=>)
// Methods, they will create names that match the model
// and you can back back to the same model on Get/Post
<label>Name:</label>
@Html.TextBoxFor(m => Model.PersonSearchModel.Name)
// or let mvc create a working label automagically
@Html.EditorFor(m => Model.PersonSearchModel.Name)
// or let mvc create the entire form..
@Html.EditorFor(m => Model.PersonSearchModel)
}
/Views/Person/Partial-SearchResults.cshtml
@model IPersonSearchResultsView
@foreach (var person in Model.PersonSearchResults )
{
<tr>
<td class="list-field">
@Html.DisplayFor(modelItem => person.Name)
</td>
// etc
</tr>
}
和最后的观点:
/Views/Person/Search.cshtml
@model PersonSearchViewModel
@Html.Partial("Partial-SearchCriteria", Model)
// easily change the order of these
<div id="searchResults">
@Html.Partial("Partial-SearchResults", Model);
</div>
现在让Ajax是pretty疯狂容易(简体和我的不完全正确):
Now enabling Ajax is pretty crazy easy (simplified and my not be exactly right):
$.Ajax({
url: '/Person/Results',
data: $('#searchCriteria').serialize(),
success: function(jsonResult)
{
$('#searchResults').innerHtml(jsonResult);
});
这篇关于保留表单值后门柱(而不是模型的一部分)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!