MVC 局部视图问题
MVC Partial Views issue
我是 MVC 的新手,我想知道是否有更好的方法来做到这一点。我有一个文本框供用户输入他们的搜索,然后根据该搜索我在所述搜索框下方显示一些结果。我试图避免在我看来有太多代码逻辑,并且想知道是否有更好的方法来处理这个问题。这是我现有的代码,根据 "Model.Results" 的值,如果我的其余逻辑通过,它将 return 3 个局部视图之一或一个按钮:
@section CustomerPrefixInfo
{
@if (Model.Results == PrefixSearch.SearchResults.CustomerFound)
{
@Html.Partial("_CustomerPrefixInfo")
}
@if (Model.Results == PrefixSearch.SearchResults.PrefixResultsFound)
{
@Html.Partial("_PrefixResults")
}
@if (Model.Results == PrefixSearch.SearchResults.AnimalsFound)
{
@Html.Partial("_AnimalSearchResults")
}
@if (Model.Results == PrefixSearch.SearchResults.ValidNewPrefix)
{
using (Html.BeginForm("Index", "PrefixManagement", new { prefix = Model.AnimalPrefix.Prefix, dbPrefix = Model.AnimalPrefix.DbPrefix }))
{
<fieldset>
<input id="btnReservePrefix" type="submit" value="Reserve Prefix" />
</fieldset>
}
}
}
我想把它放在一个控制器中,这样它 return 就是要显示的视图,然后只在页面上显示该视图。在做了一些研究之后,我认为使用 Ajax.BeginForm 并将 InsertionMode 设置为 InsertAfter 可以解决问题:
@using (Ajax.BeginForm("GenericSearch", "Home", FormMethod.Post, new AjaxOptions { InsertionMode = InsertionMode.InsertAfter, UpdateTargetId = "searchResults" }))
{
<fieldset>
<input id="btnPrefixSearch" type="submit" value="Prefix Search/Validate"/>
@Html.EditorFor(model => model.Input)
</fieldset>
<div id="searchResults">
</div>
}
我的 GenericSearch Action 然后使用一个开关来决定将哪个部分视图 return:
public ActionResult GenericSearch(PrefixSearch prefixSearch)
{
//some database logic here to get the results
switch (prefixSearch.Results)
{
case PrefixSearch.SearchResults.CustomerFound:
return PartialView("_CustomerPrefixInfo", prefixSearch);
case PrefixSearch.SearchResults.PrefixResultsFound:
return PartialView("_PrefixResults", prefixSearch);
case PrefixSearch.SearchResults.AnimalsFound:
return PartialView("_AnimalSearchResults", prefixSearch);
default:
return null;
}
}
但是当我尝试这样做时,它会将部分视图放在新页面上。
这是我的部分观点之一(他们3个都与此基本相同)
@model MVC_Test_Project.Models.PrefixSearch
@{
ViewBag.Title = "PrefixResults";
}
@{
Layout = null;
}
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.PrefixResults[0].Prefix)
</th>
<th>
@Html.DisplayNameFor(model => model.PrefixResults[0].CustomerCount)
</th>
<th>
@Html.DisplayNameFor(model => model.PrefixResults[0].Link)
</th>
</tr>
@foreach (var item in Model.PrefixResults)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Prefix)
</td>
<td>
@Html.DisplayFor(modelItem => item.CustomerCount)
</td>
<td>
<a href="@item.Link">edit</a>
</td>
</tr>
}
</table>
如有任何帮助,我们将不胜感激!
编辑 这只是一个有用的提示,以防万一有人犯了和我一样的愚蠢错误,确保你的包在你的脚本之前被调用。
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>
当有人提到要使用它们时,我在最后两行中添加了这些内容,但它们在我的包之上....因此 ajax 无法正常工作。感谢大家的帮助,现在一切都很好!
--约瑟夫
确保在要执行 Ajax 的页面顶部包含 jQuery 和 jquery.unobtrusive-ajax.js
(或 jquery.unobtrusive-ajax.min.js
)。
像这样:
<script src="~/scripts/jquery-1.x.x.js" />
<script src="~/scripts/jquery.unobtrusive-ajax.js" />
...
The rest of your page down here
...
这允许 Partial 的回发在页面内呈现,而不是每次都重定向您。
如果您还没有 jQuery 文件,或者不确定如何包含它们;在这里阅读:http://www.c-sharpcorner.com/UploadFile/4fcb5a/update-a-div-and-partial-view-using-ajax-beginform-on-form-s/ - 它非常有用。
确保在您的 web.config 文件中启用了 Unobtrusive JS。它们在 <appsettings>
节点中看起来像这样:
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
如果您正在使用验证 - 我怀疑您是为了搜索;但请听我说 - 您可能还想包括 jquery.validate.js
和 jquery.validate.unobtrusive.js
。这可以允许客户端验证(在可能的情况下)使用户体验更加流畅。
注意:还有其他方法来执行Ajax请求;例如在您自己的 JS 脚本中创建它 - 这个示例是使用已经可用且备受喜爱的库的最简单方法:)
希望对您有所帮助!
编辑
switch
的 return 部分视图然后可以仅从您的控制器内部完成。您可以从页面视图中删除逻辑。
然后 Ajax 将负责替换您提供给 Ajax.BeginForm
助手的 div 的 ID 的内容。
您可以完全替换搜索表单 - 通过使用它的 ID,或者更好 - 在页面中放置一个空的 <div>
容器,准备好在以下位置显示结果:
<div id="searchResults"></div>
然后 Ajax 将 return 部分视图并将内容放入您的 searchResults
div.
编辑 2
我注意到你 Ajax.BeginForm
的 AjaxOptions
对象中你缺少 HttpMethod = "POST"
。
AjaxOptions
应该看起来像这样:
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "searchResults",
InsertionMode = InsertionMode.Replace
}
I would like to put this inside a controller so that it just returns the view
看起来很简单:
视图模型:
public class MyModel
{
public string PageToRender { get; set; }
}
控制器动作
public ActionResult DoLogic()
{
//var Results = ?? as The ENum
switch(Results)
{
PrefixSearch.SearchResults.CustomerFound:
model.PageToRender = "_CustomerPrefixInfo";
// etc etc
}
return View(model);
}
查看:
@{if (!string.IsNullOrEmpty(model.PageToRender))
Html.RenderPartial(model.PageToRender);}
虽然我可能会装饰枚举:
public enum SearchResults
{
[Display(Name="_CustomerPrefixInfo")]
CustomerFound
}
然后没有switch语句,你只是grab the enum value display attribute's name value.
我是 MVC 的新手,我想知道是否有更好的方法来做到这一点。我有一个文本框供用户输入他们的搜索,然后根据该搜索我在所述搜索框下方显示一些结果。我试图避免在我看来有太多代码逻辑,并且想知道是否有更好的方法来处理这个问题。这是我现有的代码,根据 "Model.Results" 的值,如果我的其余逻辑通过,它将 return 3 个局部视图之一或一个按钮:
@section CustomerPrefixInfo
{
@if (Model.Results == PrefixSearch.SearchResults.CustomerFound)
{
@Html.Partial("_CustomerPrefixInfo")
}
@if (Model.Results == PrefixSearch.SearchResults.PrefixResultsFound)
{
@Html.Partial("_PrefixResults")
}
@if (Model.Results == PrefixSearch.SearchResults.AnimalsFound)
{
@Html.Partial("_AnimalSearchResults")
}
@if (Model.Results == PrefixSearch.SearchResults.ValidNewPrefix)
{
using (Html.BeginForm("Index", "PrefixManagement", new { prefix = Model.AnimalPrefix.Prefix, dbPrefix = Model.AnimalPrefix.DbPrefix }))
{
<fieldset>
<input id="btnReservePrefix" type="submit" value="Reserve Prefix" />
</fieldset>
}
}
}
我想把它放在一个控制器中,这样它 return 就是要显示的视图,然后只在页面上显示该视图。在做了一些研究之后,我认为使用 Ajax.BeginForm 并将 InsertionMode 设置为 InsertAfter 可以解决问题:
@using (Ajax.BeginForm("GenericSearch", "Home", FormMethod.Post, new AjaxOptions { InsertionMode = InsertionMode.InsertAfter, UpdateTargetId = "searchResults" }))
{
<fieldset>
<input id="btnPrefixSearch" type="submit" value="Prefix Search/Validate"/>
@Html.EditorFor(model => model.Input)
</fieldset>
<div id="searchResults">
</div>
}
我的 GenericSearch Action 然后使用一个开关来决定将哪个部分视图 return:
public ActionResult GenericSearch(PrefixSearch prefixSearch)
{
//some database logic here to get the results
switch (prefixSearch.Results)
{
case PrefixSearch.SearchResults.CustomerFound:
return PartialView("_CustomerPrefixInfo", prefixSearch);
case PrefixSearch.SearchResults.PrefixResultsFound:
return PartialView("_PrefixResults", prefixSearch);
case PrefixSearch.SearchResults.AnimalsFound:
return PartialView("_AnimalSearchResults", prefixSearch);
default:
return null;
}
}
但是当我尝试这样做时,它会将部分视图放在新页面上。
这是我的部分观点之一(他们3个都与此基本相同)
@model MVC_Test_Project.Models.PrefixSearch
@{
ViewBag.Title = "PrefixResults";
}
@{
Layout = null;
}
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.PrefixResults[0].Prefix)
</th>
<th>
@Html.DisplayNameFor(model => model.PrefixResults[0].CustomerCount)
</th>
<th>
@Html.DisplayNameFor(model => model.PrefixResults[0].Link)
</th>
</tr>
@foreach (var item in Model.PrefixResults)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Prefix)
</td>
<td>
@Html.DisplayFor(modelItem => item.CustomerCount)
</td>
<td>
<a href="@item.Link">edit</a>
</td>
</tr>
}
</table>
如有任何帮助,我们将不胜感激!
编辑 这只是一个有用的提示,以防万一有人犯了和我一样的愚蠢错误,确保你的包在你的脚本之前被调用。
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>
当有人提到要使用它们时,我在最后两行中添加了这些内容,但它们在我的包之上....因此 ajax 无法正常工作。感谢大家的帮助,现在一切都很好! --约瑟夫
确保在要执行 Ajax 的页面顶部包含 jQuery 和 jquery.unobtrusive-ajax.js
(或 jquery.unobtrusive-ajax.min.js
)。
像这样:
<script src="~/scripts/jquery-1.x.x.js" />
<script src="~/scripts/jquery.unobtrusive-ajax.js" />
...
The rest of your page down here
...
这允许 Partial 的回发在页面内呈现,而不是每次都重定向您。
如果您还没有 jQuery 文件,或者不确定如何包含它们;在这里阅读:http://www.c-sharpcorner.com/UploadFile/4fcb5a/update-a-div-and-partial-view-using-ajax-beginform-on-form-s/ - 它非常有用。
确保在您的 web.config 文件中启用了 Unobtrusive JS。它们在 <appsettings>
节点中看起来像这样:
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
如果您正在使用验证 - 我怀疑您是为了搜索;但请听我说 - 您可能还想包括 jquery.validate.js
和 jquery.validate.unobtrusive.js
。这可以允许客户端验证(在可能的情况下)使用户体验更加流畅。
注意:还有其他方法来执行Ajax请求;例如在您自己的 JS 脚本中创建它 - 这个示例是使用已经可用且备受喜爱的库的最简单方法:)
希望对您有所帮助!
编辑
switch
的 return 部分视图然后可以仅从您的控制器内部完成。您可以从页面视图中删除逻辑。
然后 Ajax 将负责替换您提供给 Ajax.BeginForm
助手的 div 的 ID 的内容。
您可以完全替换搜索表单 - 通过使用它的 ID,或者更好 - 在页面中放置一个空的 <div>
容器,准备好在以下位置显示结果:
<div id="searchResults"></div>
然后 Ajax 将 return 部分视图并将内容放入您的 searchResults
div.
编辑 2
我注意到你 Ajax.BeginForm
的 AjaxOptions
对象中你缺少 HttpMethod = "POST"
。
AjaxOptions
应该看起来像这样:
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "searchResults",
InsertionMode = InsertionMode.Replace
}
I would like to put this inside a controller so that it just returns the view
看起来很简单:
视图模型:
public class MyModel
{
public string PageToRender { get; set; }
}
控制器动作
public ActionResult DoLogic()
{
//var Results = ?? as The ENum
switch(Results)
{
PrefixSearch.SearchResults.CustomerFound:
model.PageToRender = "_CustomerPrefixInfo";
// etc etc
}
return View(model);
}
查看:
@{if (!string.IsNullOrEmpty(model.PageToRender))
Html.RenderPartial(model.PageToRender);}
虽然我可能会装饰枚举:
public enum SearchResults
{
[Display(Name="_CustomerPrefixInfo")]
CustomerFound
}
然后没有switch语句,你只是grab the enum value display attribute's name value.