Значок загрузки Ajax MVC 3 при переходе на новую страницу / метод действия
Я много искал, как создать навигационную ссылку, которая будет отображать значок загрузки ajax, когда метод действия выполняется в MVC 3 с использованием механизма представления Razor. Хотя я нашел много информации о добавлении значка загрузки, все они, похоже, относятся к публикации данных в текущем представлении.
У меня есть простая страница меню, в которой есть ссылки на действия для вызова методов действия на других страницах, которые, в свою очередь, будут отображать представление. Пример перехода к методам действий OrdersController и Index приведен ниже.
Menu.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.
Menu.cshtml
@Ajax.ActionLink("Orders", "Index", "Orders", new AjaxOptions { LoadingElementId="ajaxLoaderDiv" });<br />
Это работает в том смысле, что отображает значок загрузки AJAX в течение нескольких секунд. И я даже могу поместить точку останова в метод действия Index в OrdersController, и он поразит его. Но когда метод действия завершается, Orders \ Index.cshtml никогда не обрабатывает страницу. Я просто остаюсь на странице Menu \ Index.cshtml.
Я знаю, что Orders / Index.cshtml должен отображать представление.
OrdersController.cs
public ActionResult Index()
{
....
return View(OrdersViewModel);
}
Что я здесь не так делаю? Возвращается ли это представление к моему вызову ajax, а не к визуализации? Как я могу получить эту функциональность?
Если я поступаю неправильно, дайте мне знать.
Должен ли я делать это внутри метода действия целевой страницы, а не по ссылке при выполнении запроса? Может быть, отображая значок загрузки в качестве первой строки кода в методе действия Index, который я запрашиваю, и снова скрывая его непосредственно перед возвратом представления?
Возможно, я бы попытался сделать это через комбинацию JQuery Show/ Hide?
<script type="text/javascript">
function showLoadingSpinner() {
$("#ajaxLoaderDiv").show();
};
function hideLoadingSpinner() {
$("#ajaxLoaderDiv").hide();
};
</script>
Заранее спасибо за и все помощь и совет
Чад
2 ответа
Мое разрешение:
Я решил свою проблему самостоятельно, но думал, что опубликую решение для любых других, которые пытаются что-то подобное.
Я сохранил ссылку на своей странице menu.cshtml как @Html.ActionLink, а не как ajax-ссылку. Но я добавил атрибут html onclick, который вызывал javacript для отображения счетчика.
menu.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 у меня есть сценарий для счетчика. на который ссылаются в моем представлении menu.cshtml: Layout = "~/Views/Shared/_Layout.cshtml";
Ниже моя полная страница _Layout.cshtml, включая ссылки на ajax и ссылки на скрипты.
_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), использует ту же страницу макета, которая содержит div ajax, она загружает новую страницу с отображением свойства div ajaxloader: ни одна из них не установлена макетом. Это приводит к удалению счетчика ajax, который отображался при загрузке страницы.
Поэтому нет необходимости когда-либо вызывать javascript, чтобы скрыть счетчик, потому что он всегда удаляется при рендеринге новой страницы.
Если кто-то еще не скажет мне, что это неуместный подход и успешно покажет мне лучший способ, я приму это как ответ.
Измените свою подпись метода действия на что-то вроде этого:
public PartialViewResult Index()
{
....
return PartialView(OrdersViewModel);
}
Кроме того, для правильной работы Ajax.ActionLink необходимо добавить ссылку на ненавязчивый ajax:
Доступно через nuget, если только оно не находится в папке скриптов.
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>