ASP.NET MVC에서 간극 "로드…"페이지를 어떻게 구현합니까?
-
22-07-2019 - |
문제
나는있다 SearchController 오랜 실행 검색을 실행하고 결과 페이지를 반환 할 수있는 조치로. 검색은 1 초에서 60 초가 소요될 수 있습니다. 검색의 URL은 양식의 HTTP GET 요청입니다. http://localhost/Search?my=query&is=fancy
내가 찾고있는 경험은 거기에있는 많은 여행 사이트와 유사합니다. 중간 "로딩 ..."페이지를 보여주고 싶습니다. 이상적으로 :
- 사용자는 검색을 다시 시작하지 않고 페이지를 다시로드 할 수 있습니다.
- 백엔드 검색이 완료되면 사용자는 결과로 리디렉션됩니다.
- 경험은 JavaScript가 비활성화 된 브라우저의 저하가 저하됩니다
- 뒤로 버튼 / 브라우저 기록에는이 간극 페이지가 포함되어서는 안됩니다.
- 짧은 검색 (1 초)의 경우 결과에 도달 할 시간이나 경험에 큰 영향을 미치지 않습니다 (크게 못생긴 페이지 플래시 등)
그것들은 좋은 것입니다. 나는 모든 아이디어에 열려 있습니다! 감사.
해결책
다음과 같은 방법으로 할 수 있습니다.
- ajax로 검색 요청 (get url)을 수행합니다.
- 검색 URL은 결과를 반환하지 않지만 실제 결과의 URL과 함께 일부 JSON 또는 XML 컨텐츠를 반환합니다.
- 클라이언트 페이지에는 Ajax 호출이 완료되기를 기다리는 동안 "로드 ..."메시지가 표시됩니다.
- 클라이언트 페이지는 완료되면 결과 페이지로 리디렉션됩니다.
jQuery를 사용하는 예 :
<div id="loading" style="display: none">
Loading...
</div>
<a href="javascript:void(0);"
onclick="searchFor('something')">Search for something</a>
<script type="text/javascript">
function searchFor(what) {
$('#loading').fadeIn();
$.ajax({
type: 'GET',
url: 'search?query=' + what,
success: function(data) {
location.href = data.ResultsUrl;
}
});
}
</script>
(편집하다:)
컨트롤러는 다음과 같습니다.
public class SearchController
{
public ActionResult Query(string q)
{
Session("searchresults") = performSearch();
return Json(new { ResultsUrl = 'Results'});
}
public ActionResult Results()
{
return View(Session("searchresults"));
}
}
의사 코드를 고려하십시오. 실제로 테스트하지 않았습니다.
다른 팁
JavaScript를 유지하려면 검색을 여러 작업으로 나눌 수 있습니다.
첫 번째 조치 (/search/? q = whodUnit)는 매개 변수에 대한 약간의 검증을 수행합니다 (양식을 다시 살펴볼 필요가 있는지 알 수 있음). 그런 다음 메타 리프레 쉬를 사용하여 브라우저를 "실제"검색 조치.
두 가지 별도의 컨트롤러 조치 (예 : 검색 및 결과)로이를 구현할 수 있습니다.
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를 사용하여 2 상 프로세스를 신호로 표시 할 수있는 단일 동작으로 다시 연마 할 수 있습니다.
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에 대한 지원이 포함되면 검색 결과가 세션, DB 등에 저장할 것임을 의미합니다.
이 경우 원하는 캐시 ubstractAtin을 "실제 검색 수행"비트의 일부로 추가하고 로딩 페이지를 우회하기 위해 캐시 링-레지 곡을 추가하십시오. 예를 들어
if (TempData[SearchLoadingPageSentKey]==null)
becomes
if (TempData[SearchLeadingPageSentKey]==null && !SearchCache.ContainsKey(q))
좋은 질문. 곧 ASP.NET MVC에서 유사한 솔루션을 직접 구현해야 할 수도 있지만 WebForms 기반 솔루션과 근본적으로 다른 구현이 필요하지는 않다고 생각합니다.
- ASP.NET의 진행률 표시 줄을 사용하여 장기 실행 작업을 실행합니다 (aspfree.com)
- 설계 패턴 : ASP.NET의 비동기 대기 상태 패턴 (MSDN)
이전에 웹 양식과의 첫 번째 링크를 기반으로 구현을 구축했습니다. 기본 프로세스는 다음과 같습니다.
- 초기 페이지는 검색 매개 변수로 요청됩니다
- 이 페이지는 장기 실행 작업을 수행하는 새로운 스레드를 시작합니다.
- 이 페이지는 몇 초마다 다시로드하도록 HTTP 새로 고침 헤더가 설정된 "Under Process"페이지로 사용자를 리디렉션합니다.
- 검색을 수행하는 스레드는 % 완료를 나타내는 "글로벌"정적 검색 프로그램 객체를 업데이트하고 Under Process Page는이를 읽고 진행 상황을 표시합니다. (각 검색은 해시 테이블의 Guid ID에 의해 저장되므로 여러 동시 검색이 지원됩니다)
- 스레드가 완료되면 검색 프로그램이 업데이트되고 아래 프로세스 페이지가이를 감지하면 최종 "결과"페이지로 리디렉션됩니다.
(MSDN의 두 번째 링크를 확실히 확인하십시오. 매우 다른 솔루션이지만 제가 훑어 본 솔루션은 아닙니다.)
이것의 이점은 JavaScript가 전혀 필요하지 않다는 것입니다. (사용자의 관점에서) 내가 생각할 수있는 가장 큰 단점은 전적으로 "Web 2.0"이 아니며 사용자는 일련의 브라우저 새로 고침을 기다려야한다는 것입니다.
@jan Willem B의 Ajax 기반 제안을 기반으로 한 것은이 멀티 스레드 대기 상태 패턴에 대한 실용적인 대안이어야합니다. 요구 사항을 가장 잘 충족시키는 것은 스스로 결정해야 할 것입니다. 내가 게시 한 aspfree.com의 예제는 대부분의 요구 사항을 충족하고 웹 양식으로 MVC와 마찬가지로 작동해야합니다.