MVC ajax从内部更新部分结果

MVC ajax update partial result from inside

本文关键字:结果 更新部 内部 ajax MVC      更新时间:2023-09-26

我有一个视图Index,其中引用了部分视图GetAlertData:

Index.cshtml

<table>
    <thead>
        <tr>
            <th>Date</th>
            <td>Message</td>
            <td>Type</td>
            <td>Actions</td>
        </tr>
    </thead>
    <tbody id="tableBody">
        @Html.Action("GetAlertData", new { selectedAlertType = Model.SelectedAlertType })
    </tbody>
</table>

GetAlertData.cshtml

foreach (var alert in Model.UserAlerts)
{
    <tr>
        <td>
            @alert.Date.ToString("d")
        </td>
        <td>
            @alert.Message
        </td>
        <td>
            @alert.AlertTypeName
        </td>
        <td>
            @Ajax.ActionLink("Dismiss", "Dismiss", new { userAlertID = alert.UserAlertID }, new AjaxOptions() { HttpMethod = "Post" })
        </td>
    </tr>
}

控制器代码

    public PartialViewResult GetAlertData(string selectedAlertType = "All")
    {
        //create viewModel
        return PartialView(viewModel);
    }
    [HttpPost]
    public ActionResult Dismiss(int userAlertID)
    {
        alertModel.DismissAlert(userAlertID);
        return RedirectToAction("Index"); //does nothing, because ajax (?)
    }

问题是这样的:我希望"父"视图从"GetAlertData"Html中刷新数据。单击解散后的操作。如何让"父"视图在警报被驳回后重新运行GetAlertData ?返回RedirectToAction没有任何作用,因为它是ajax调用。

我知道我可以在父视图中设置一个javascript方法,然后在OnSuccess中调用解散ajax调用,但这似乎有点混乱,我想知道MVC框架或辅助方法中是否有任何东西可以帮助我做到这一点

使用来自服务器的内容更新页面内容只有两种方法:1)重新加载整个页面或2)AJAX。

如果您只想更新页面的一部分而不引起重新加载,那么您必须使用AJAX请求一些将返回所需信息的操作,然后使用JS替换DOM中的页面部分。因为这本质上是关于重新加载一个分部,所以你需要一个返回那个分部的操作。另外,由于已经使用了子操作,因此也可以对这个操作使用相同的操作。只要确保删除[ChildActionOnly](如果存在),这样操作就会暴露给路由框架。

如果你将ActionLink移动到jQuery/Javascript点击事件,那么你可以从那里调用解散返回一个成功/错误标志。如果解散成功,那么用另一个Ajax调用GetAlertData方法,并使用返回的HTML来替换表主体。你可能需要做一些其他的改变

我解决了这个问题。我将重定向操作从"Index"更改为"GetAlertData",并将UpdateTargetId选项设置为与父视图相同。单击解散按钮后,它将用新结果替换部分视图的内容。

对我来说,这个答案唯一的问题是我必须在父视图("tableBody")中引用元素的id。我试图将整个子视图包装在一个div中并替换它,但这导致了重复和糟糕的格式。这可能部分是因为<table><div><tr>不是完全有效的HTML。

新建子视图代码:

@{
    var ajaxOpts = new AjaxOptions()
    {
        UpdateTargetId = "tableBody",
        HttpMethod = "Post",
    };
    if (Model.UserAlerts != null)
    {
        foreach (var alert in Model.UserAlerts)
        {
            <tr>
                <td>
                    @alert.Date.ToString("d")
                </td>
                <td>
                    @alert.Message
                </td>
                <td>
                    @alert.AlertTypeName
                </td>
                <td>
                    @Ajax.ActionLink("Dismiss", "Dismiss", new { userAlertID = alert.UserAlertID }, ajaxOpts)
                </td>
            </tr>
        }
    }
}