【问题标题】:MVC Partial view with controller, ajax - how do I ge the partial controller to get data?带有控制器、ajax 的 MVC 部分视图 - 如何让部分控制器获取数据?
【发布时间】:2013-05-05 06:47:32
【问题描述】:

我正在学习 MVC,对此感到困惑。我正在尝试将一些获取数据并将其显示在 WebGrid 中的通用代码分解为可以在多个页面上使用的局部视图。

我的 home 控制器 Index 方法只是返回 View()。主页视图如下所示:

@using (Ajax.BeginForm("SearchAction", "Search",
    new AjaxOptions { UpdateTargetId = "data-grid", HttpMethod = "Post" }))
{
    @Html.TextBoxFor(model => model.name)
    <input type="submit" value="Search" />
}

@{
<div id="data-grid">
    @Html.Partial("SearchResults", Model)
</div>
}

我正在尝试使用 Ajax 来避免在单击 WebGrid 分页器链接时丢失我的搜索表单数据,这些链接呈现为普通链接。

我的 SearchController 如下所示:

public ActionResult SearchAction(string name)
{
    return RedirectToAction("SearchResults", new { name = name });
}

public ActionResult SearchResults(string name)
{
    //does database query and sticks results in the viewbag
    //filter on optional name parameter

    VieweBag.Members = MyQueryResults;
    return PartialView();
}

我的 SearchResults 共享视图,数据通过 ViewBag.Members 传入:

@{
    var grid = new WebGrid(null, rowsPerPage: ViewBag.Pagesize);
    grid.Bind(ViewBag.Members);
    @grid.GetHtml(// etc. etc.)
}

我得到的结果是 ViewBag.Pagesize 和 ViewBag.Members 绑定失败,因为 viewbag 中没有数据。显然,我的部分控制器没有被调用来执行初始查询并将内容放入第一次加载主页时的 ViewBag 中。我该如何做到这一点?

另一个奇怪的事情是,如果我只是将数据库查询代码复制到我的家庭控制器(它原来所在的位置)以强制执行原始查询,那么如果我将一些文本放入搜索字段并进行搜索,部分视图在新页面上自行呈现。为什么会这样,我以为它只会作为我主页的一部分呈现。

我从不同的答案/地方拼凑出这个部分观点,毫无疑问,我遇到了可怕的错误:\

【问题讨论】:

    标签: asp.net-mvc-4


    【解决方案1】:

    部分页面不会通过控制器,而是直接渲染视图。如果要将视图数据传递给局部视图,则有一个采用 viewdata 字典的重载函数。对不起,我不能更详细,但我在手机上(等我儿子在另一个房间睡着):)

    更新:

    如果要为局部视图触发GET 操作,可以使用Html.Action。以下是一些有用的链接:

    此外,将表单标签移动到局部视图中可能更有意义,但这些是清理代码时的详细信息。

    【讨论】:

    • 等等,“不会通过控制器”是什么意思?我很困惑,我有一个用于局部视图的控制器,它被调用了,但只有在我搜索时......而不是在页面加载时。如何强制在页面加载时调用局部视图控制器,以便局部视图具有数据?
    • @EricSassaman,我更新了我的答案。希望能帮助到你。正如您所拥有的,部分视图在页面首次加载时不会调用服务器。将触发的控制器操作取决于您如何设置路由。但是,由于您已在表单标记中定义它,因此将在回发时调用搜索控制器。如果将表单移到局部视图中,则可以更好地定位回发(例如,您可能希望在父页面上使用不同的表单和回发)。
    • 已修复!!我的修复:1)包括 jquery.unobtrusive-ajax.js - 这修复了单独页面上的呈现。 2)用@Html.Action(“SearchResults”,“Search”)替换@Html.Partial,这会在页面加载时加载网格(谢谢!!)3)删除搜索控制器中无用的SearchAction()和4)设置HttpMethod = Ajax.BeginForm AjaxOptions 中的“GET”(哦!)。我的表单输入 ID 和搜索控制器参数之间也存在不匹配。还要感谢“Pro ASP.NET MVC 4”一书在全天阅读狂欢中提供的一些重要线索,哇哦。
    【解决方案2】:

    Jonass 是对的,ViewBag 只在 Controller 和 View 之间传播。

    您可以做的一件事是使局部视图的模型与您放入 ViewBag 的数据类型相同。

    例如,如果您的 MyQueryResults 属于以下类型:

    IEnumerable<Result>
    

    在你的局部视图中你会添加

    @Model IEnumerable<Result>
    

    然后在主视图中,您将通过 Render 方法传递它:

    @Html.Partial("SearchResults", ViewBag.Members);
    

    您需要稍微调整一下以确保它是正确的类型,但这应该可以解决问题。

    祝你好运!

    【讨论】:

    • 嗯,问题是我的 SearchResults 控制器永远不会在页面加载时被调用。只有我的主页控制器可以。我尝试进行您建议的更改,当我在部分视图控制器 (SearchController) 中放置断点时,它从未在页面加载时命中它。所以我的模型在我的部分视图中是空的。我需要在两个控制器中复制我的数据库查询代码吗?完全违背了我在这里尝试做的目的......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 2015-06-05
    • 2010-09-22
    • 2017-04-14
    • 2015-12-06
    • 1970-01-01
    相关资源
    最近更新 更多