4

我一直在广泛搜索如何创建一个导航链接,该链接将在使用 Razor 视图引擎在 MVC 3 中运行操作方法时显示一个 ajax 加载图标。虽然我找到了大量关于添加加载图标的信息,但它们似乎都与在当前视图中发布数据有关。

我有一个简单的菜单页面,其中包含用于调用其他页面上的操作方法的操作链接,这反过来将呈现一个视图。下面显示了一个转到 OrdersController 和 Index 操作方法的示例。

菜单.cshtml

@Html.ActionLink("Orders", "Index", "Orders",null,new { id = "OrderLink" })<br />

我正在尝试以一种方式修改上面的链接,即在处理 Index 操作和返回视图之前,显示一个 ajax 加载图标。

我创建了一个包含加载图标的 div,并将其放置在我共享的 _Layout.cshtml 页面中。

_Layout.cshtml

<div id="ajaxLoaderDiv" style="position:fixed; top:40%; left:45%; z-index:1234; display:none;">
    <img src="@Url.Content("~/Images/AjaxLoaderImg.gif")" alt="Loading..."class="ajax-loader" />
</div>

为了尝试显示 ajax 加载图标,我尝试将链接更改为 Ajax ActionLink。

菜单.cshtml

@Ajax.ActionLink("Orders", "Index", "Orders", new AjaxOptions { LoadingElementId="ajaxLoaderDiv" });<br />

这在它显示 ajax 加载图标几秒钟的意义上是有效的。我什至可以在 OrdersController 的 Index 操作方法中放置一个断点,它会命中它。但是当 Action 方法完成时,Orders\Index.cshtml 永远不会呈现到页面上。我只是留在 Menu\Index.cshtml 页面上。

我知道 Orders/Index.cshtml 应该呈现一个视图。

OrdersController.cs

public ActionResult Index()
{
    ....

return View(OrdersViewModel);
}

我在这里做错了什么?这个视图是否被返回给我的 ajax 调用而不是渲染?我怎样才能获得这个功能?

如果我以错误的方式处理此问题,请告诉我。

发出请求时,我应该在目标页面的操作方法中而不是在链接上执行此操作吗?也许通过将加载图标显示为我请求的 Index 操作方法中的第一行代码,并在返回视图之前再次隐藏它?

我可能会尝试通过 JQuery 显示/隐藏组合来做到这一点?

<script type="text/javascript">
    function showLoadingSpinner() {
        $("#ajaxLoaderDiv").show();
    };
    function hideLoadingSpinner() {
        $("#ajaxLoaderDiv").hide();
    };

</script>

提前感谢所有的帮助和建议

乍得

4

2 回答 2

9

我的决心:

我自己解决了我的问题,但我想我会为任何其他尝试类似事情的人发布解决方案。

我将 menu.cshtml 页面上的链接保留为 @Html.ActionLink 而不是 ajax 链接。但是我添加了一个 onclick html 属性,该属性调用 javacript 来显示微调器。

菜单.cshtml

@{
    ViewBag.Title = "Menu";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<div class="container" style="text-align:center">
    <div>
        @Html.ActionLink("Orders", "Index", "Orders", null, new { id = "OrderLink", onclick="showPageLoadingSpinner()" })
    </div>
</div>

我的 _Layout.cshtml 部分视图中有微调器的 scipt。在我的 menu.cshtml 视图中引用: Layout = "~/Views/Shared/_Layout.cshtml";

下面是我的完整 _Layout.cshtml 页面,包括 ajax div 和脚本引用。

_Layout.cshtml

<html>
<head>
    @Content.Script("jquery-1.5.1.min.js", Url)
    @Content.Script("jquery.unobtrusive-ajax.min.js", Url)
</head>

<body>
    <div id="ajaxLoaderDiv" style="position:fixed; top:40%; left:45%; z-index:1234; display:none;">
    </div>
    <div class="container">
         @RenderBody()
    </div>
</body>
</html>

<script type="text/javascript">
function showPageLoadingSpinner() {
     $('#ajaxLoaderDiv').show();
     $('#ajaxLoaderDiv').append(
                '<img src="@Url.Content("~/Images/AjaxLoaderImg.gif")" alt="Loading..."class="ajax-loader" />'
     );
 }

 function hidePageLoadingSpinner() {
     setTimeout(function () {
         $('.ajax-loader').remove();
         $('#ajaxLoaderDiv').hide();
     }, 20000);
 }

</script>

这对我有用,因为在 menu.cshtml 页面上,当您单击链接时,javascript 将在 actionlink 将您发送到下一页之前运行显示微调器。因此,您将在加载您导航到的页面时看到微调器。

当新页面准备就绪时,它将呈现并显示。虽然您被发送到的新页面 (Orders/Index.cshtml) 使用包含 ajax div 的相同布局页面,但它使用布局设置的 ajaxloader div 属性 display:none 加载新页面。这最终会删除加载页面时显示的 ajax 微调器。

因此,无需调用 javascript 来隐藏微调器,因为它总是在新页面呈现时被删除。

除非其他人告诉我这是一种不合适的方法并成功地向我展示了更好的方法,否则我将接受这个作为答案。

于 2013-12-11T17:20:31.180 回答
0

将您的操作方法签名更改为如下所示:

public PartialViewResult Index()
{
    ....

return PartialView(OrdersViewModel);
}

此外,要使 Ajax.ActionLink 正常工作,您需要添加对不显眼的 ajax 的引用:

除非它不在您的脚本文件夹中,否则可通过 nuget 获得。

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
于 2013-10-25T17:10:53.440 回答