MVC局部视图问题



我对MVC非常陌生,我正在努力找出是否有更好的方法来做到这一点。我有一个文本框供用户在搜索中使用,然后基于该搜索,我在所述搜索框下方显示一些结果。我正在努力避免在我的视图中有太多的代码逻辑,并想知道是否有更好的方法来处理这一问题。这是我现有的代码,根据"Model.Results"的值,如果我的其余逻辑通过,它将返回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>
        }
    }
}

我想把它放在一个控制器里,这样它就可以返回要显示的视图,然后在页面上显示该视图。在做了一些重新整理之后,我认为使用InsertionMode设置为InsertAfter的Ajax.BeginForm就可以了:

@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操作使用开关来决定返回哪个部分视图:

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没有工作。感谢大家的帮助,现在一切都很好!--Joseph

我想把这个放在控制器里,这样它就可以返回视图

看起来很直接:

ViewModel:

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

尽管我可能会装饰Enum:

public enum SearchResults
{
  [Display(Name="_CustomerPrefixInfo")]
  CustomerFound
}

然后没有switch语句,只获取枚举值显示属性的名称值。

确保在要执行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.jsjquery.validate.unobtrusive.js。这可以允许客户端验证(在可能的情况下),使用户体验更加流畅。

注意:还有其他处理Ajax请求的方法;比如在自己的JS脚本中创建它——这个例子是使用已经可用且备受喜爱的库最简单的:)

希望这能有所帮助!

编辑
返回Partial视图的switch可以仅从控制器内部完成。您可以从页面视图中删除逻辑。

Ajax将负责替换您提供给Ajax.BeginForm助手的div ID的内容。

您可以使用ID完全替换搜索表单,或者更好地在页面中放置一个空的<div>容器,准备在中显示结果

<div id="searchResults"></div>

Ajax将返回Partial视图,并将内容放入searchResults分区中

编辑2

我注意到在您的Ajax.BeginFormAjaxOptions对象中缺少HttpMethod = "POST"

AjaxOptions应该看起来像这样:

new AjaxOptions {
            HttpMethod = "POST",
            UpdateTargetId = "searchResults",
            InsertionMode = InsertionMode.Replace
}

最新更新