我的 MVC
项目中有一个解决方案,它允许我随时显示和/或隐藏加载屏幕:
$("#divLoading").show();
$("#divLoading").hide();
这个“divLoading”本质上包含加载屏幕。现在这个解决方案在大多数情况下都可以正常工作;即使我想使用 Ajax 以便在脚本开始执行时显示加载屏幕并在函数完成时隐藏它。像这样的东西:
$("#btnTreatData").click(function () {
$("#divLoading").show();
// Some stuff
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '@Url.Action("TreatValidationData", "Article")',
type: "POST",
data: JSON.stringify({ listOfCheckedData: listOfCheckedData }),
success: function (result) {
$("#tableControl").html(result);
$("#divLoading").hide();
}
});
}
这很好用。然而,有一种特定的边缘情况我无法让它正常工作。
本质上,该项目使用名为 EEPlus ( http://epplus.codeplex.com/ ) 的插件来将数据导出到 XLS 文件中。这对于用户来说非常实用,因为他们只需单击按钮即可,并且不涉及重定向;文件完成后,浏览器会提示用户下载它。
本质上,我的导出方法执行如下操作:
public void ExportListUsingEPPlus(string filter, string type)
{
// A boat load of data processing and formatting that isn't relevant here
// Once the work is done:
// Write in an Excel file
using (var memoryStream = new MemoryStream())
{
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", $"attachment; filename={filename}.xlsx");
excel.SaveAs(memoryStream);
memoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
您会注意到此方法不会返回任何内容。不需要;在 View 本身中,它是这样调用的:
<li class="separator"><input value="Export xls" class="add" name="btn_submit" id="btn_excel" type="button" onClick="location.href='@Url.Action("ExportListUsingEPPlus", "Article", new { filter = @ViewBag.CurrentFilter, type="TEST"})'"></li>
这没关系......除了如果我尝试为此使用加载屏幕,因为导出数据可能需要很长时间:
function exportWithLoadingScreen()
{
$("#divLoading").show();
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '@Url.Action("ExportListUsingEPPlus", "Article", new { filter = @ViewBag.CurrentFilter, type = "TEST" })',
type: "POST"
}).complete(function (result) { $("#divLoading").hide();});
}
Ajax :
不触发“成功”事件。
不会触发“失败”事件。
处理一个“完整”事件...但是,当然,如果没有 location.href = '...',它实际上不会执行任何操作(文件是在内存中创建的,但用户永远不会提示下载)。
如果我尝试使用相同的东西但关心 location.href,它会过早触发“完整”事件,可能是因为它只关心重定向何时完成,而不是方法完成时!
我真的不知道此时我还能尝试什么,但是为此显示加载屏幕非常重要,因为它确实可能需要很长时间。
关于我还能做些什么还有什么想法吗?我将不胜感激!
编辑:我会更加精确和简洁。这:
function exportWithLoadingScreen() {
$("#divLoading").show();
location.href = '@Url.Action("ExportListUsingEPPlus", "Article", new { filter = @ViewBag.CurrentFilter, type = "TEST" })';
$("#divLoading").hide();
}
不起作用,因为所有操作都是同时进行的,所以我必须使用ajax。但这:
function exportWithLoadingScreen() {
$("#divLoading").show();
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '@Url.Action("ExportListUsingEPPlus", "Article", new { filter = @ViewBag.CurrentFilter, type = "TEST" })',
type: "POST"
}).complete(function (result) { $("#divLoading").hide(); })
};
也不起作用,因为 location.href 未执行(=> 不会提示用户下载)。但这:
function exportWithLoadingScreen() {
$("#divLoading").show();
$.ajax({
contentType: 'application/json; charset=utf-8',
url: '@Url.Action("ExportListUsingEPPlus", "Article", new { filter = @ViewBag.CurrentFilter, type = "TEST" })',
type: "POST"
}).complete(function (result) { window.location.assign(result);})
};
不起作用,因为返回的数据完全错误(服务器错误),因为 ExportListUsingEPPlus 方法没有返回任何内容。
编辑编辑:编辑问题的标题以重新聚焦问题。
最佳答案
我认为造成困惑的原因是,您想要使用 Ajax 调用,但也需要重定向页面。
Ajax 用于从服务器请求数据返回当前页面,以便您可以使用新数据更新当前页面。
重定向会放弃当前页面并将其完全替换为新页面。
这是另一个解释它的答案,它可以模拟 Ajax 请求 - 但如果它是重定向,它仍然不是 Ajax 请求...
关于javascript - ajax 调用中的 C# MVC Razor 5 : location. href,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42342793/