我有一个 SearchController,其操作可以执行一些长时间运行的搜索并返回结果页面。搜索可能需要 1 到 60 秒的时间。搜索的 URL 是以下形式的 HTTP GET 请求:http://localhost/Search?my=query&is=fancy
我正在寻找的体验与许多旅游网站相似。我想显示一个中间的“正在加载...”页面,理想情况下:
- 用户可以在不重新开始搜索的情况下重新加载页面
- 后端搜索完成后,用户将被重定向到结果
- 禁用 JavaScript 的浏览器的体验会下降
- 后退按钮/浏览器历史不应包含此插页。
- 在短搜索的情况下(1 秒),它不会对获得结果的时间或体验(非常难看的页面闪烁,无论如何)产生重大影响
那些是可有可无的。我对所有想法持开放态度!谢谢。
最佳答案
为了保持无 javascript,您可以将搜索分解为多个操作。
第一个操作 (/Search/?q=whodunit) 只是对您的参数进行一些验证(这样您就知道是否需要重新显示表单)然后返回一个使用元刷新指向浏览器回到“真正的”搜索 Action 。
您可以使用两个单独的 Controller 操作(比如搜索和结果)来实现:
public ActionResult Search(string q)
{
if (Validate(q))
{
string resultsUrl = Url.Action("Results", new { q = q });
return View("ResultsLoading", new ResultsLoadingModel(resultsUrl));
}
else
{
return ShowSearchForm(...);
}
}
bool Validate(string q)
{
// Validate
}
public ActionResult Results(string q)
{
if (Validate(q))
{
// Do Search and return View
}
else
{
return ShowSearchForm(...);
}
}
但就刷新而言,这会给您带来一些障碍。因此,您可以将它们重新合并回单个操作,该操作可以使用 TempData 向自己发出两阶段过程的信号。
static string SearchLoadingPageSentKey = "Look at me, I'm a magic string!";
public ActionResult Search(string q)
{
if (Validate(q))
{
if (TempData[SearchLoadingPageSentKey]==null)
{
TempData[SearchLoadingPageSentKey] = true;
string resultsUrl = Url.Action("Search", new { q = q });
return View("ResultsLoading", new ResultsLoadingModel(resultsUrl));
}
else
{
// Do actual search here
return View("SearchResults", model);
}
}
else
{
return ShowSearchForm(...);
}
}
这涵盖了第 2、3、4 点和可以说是第 5 点。
包含对#1 的支持意味着您要将搜索结果存储在 session 、数据库等中。
在这种情况下,只需添加所需的缓存实现作为“在此处进行实际搜索”位的一部分,并添加检查缓存结果以绕过加载页面。例如
if (TempData[SearchLoadingPageSentKey]==null)
成为
if (TempData[SearchLeadingPageSentKey]==null && !SearchCache.ContainsKey(q))
关于c# - 如何在 ASP.NET MVC 中实现插页式 "loading..."页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1650776/