Dowiaduję się o Progressive Enhancement i mam pytanie dotyczące widoków AJAXifying. W moim projekcie MVC 3 mam stronę układu, stronę Viewstart i dwa zwykłe widoki.
Strona Viewstart znajduje się w katalogu głównym folderu Views, a zatem ma zastosowanie do wszystkich widoków. Określa, że wszystkie widoki powinny być używane _Layout.cshtml
na stronie układu. Strona układu zawiera dwa łącza nawigacyjne, po jednym dla każdego widoku. Linki służą @Html.ActionLink()
do wyświetlania się na stronie.
Teraz dodałem jQuery i chcę przejąć te linki i użyć Ajax do dynamicznego ładowania ich zawartości na stronie.
<script type="text/javascript">
$(function () {
$('#theLink').click(function () {
$.ajax({
url: $(this).attr('href'),
type: "GET",
success: function (response) {
$('#mainContent').html(response);
}
});
return false;
});
});
</script>
Są dwa sposoby, aby to zrobić, ale nie podoba mi się żaden z nich:
1) Mogę pobrać całą zawartość widoku i umieścić ją w częściowym widoku, a następnie wywołać widok częściowy w widoku głównym podczas renderowania. W ten sposób, używając Request.IsAjaxRequest()
w kontrolerze, mogę zwrócić View()
lub zwrócić w PartialView()
zależności od tego, czy żądanie jest żądaniem Ajax. Nie mogę zwrócić zwykłego widoku do żądania Ajax, ponieważ wtedy użyłby on strony układu i dostałbym drugą kopię wstrzykniętej strony układu. Jednak nie podoba mi się to, ponieważ zmusza mnie to do tworzenia pustych widoków z tylko jednym @{Html.RenderPartial();}
w nich dla standardowych żądań GET.
public ActionResult Index()
{
if (Request.IsAjaxRequest())
return PartialView("partialView");
else
return View();
}
Następnie w Index.cshtml zrób to:
@{Html.RenderPartial("partialView");}
2) Mogę usunąć oznaczenie układu z _viewstart i określić je ręcznie, jeśli żądanie NIE jest Ajax:
public ActionResult Index()
{
if (Request.IsAjaxRequest())
return View(); // Return view with no master.
else
return View("Index", "_Layout"); // Return view with master.
}
Czy ktoś ma lepszą sugestię? Czy istnieje sposób na zwrócenie widoku bez strony układu? O wiele łatwiej byłoby wyraźnie powiedzieć „nie dołączaj swojego układu”, jeśli jest to żądanie AJAX, niż byłoby jawnie dołączyć układ, jeśli nie jest to AJAX.
Layout = ViewBag.LayoutFile
.Po prostu umieść poniższy kod na górze strony
źródło
Wolę i używam twojej opcji nr 1. Nie podoba mi się # 2, ponieważ dla mnie
View()
oznacza, że zwracasz całą stronę. Powinna to być w pełni dopracowana i poprawna strona HTML po zakończeniu pracy silnika widoku.PartialView()
został stworzony, aby zwracać dowolne fragmenty kodu HTML.Nie sądzę, żeby to wielka sprawa mieć pogląd, który nazywa się tylko częściowym. Nadal jest SUCHY i pozwala na użycie logiki częściowej w dwóch scenariuszach.
Wiele osób nie lubi fragmentować ścieżek połączeń swoich działań
Request.IsAjaxRequest()
i potrafię to docenić. Ale IMO, jeśli wszystko, co robisz, to decyzja, czy zadzwonić,View()
czyPartialView()
też oddział nie jest wielkim problemem i jest łatwy w utrzymaniu (i testowaniu). Jeśli okaże się, że używaszIsAjaxRequest()
do określania dużej części tego, jak rozgrywa się Twoja akcja, utworzenie oddzielnej akcji AJAX jest prawdopodobnie lepsze.źródło
Utwórz dwa układy: 1. pusty układ, 2. main layout, a następnie zapisz w pliku _viewStart ten kod:
oczywiście może to nie jest najlepsze rozwiązanie
źródło
Nie musisz w tym celu tworzyć pustego widoku.
W kontrolerze:
zwrócenie PartialViewResult spowoduje przesłonięcie definicji układu podczas renderowania odpowiedzi.
źródło
W ASP.NET 5 nie jest już dostępna zmienna żądania. Możesz teraz uzyskać do niego dostęp za pomocą Context.Request
Również nie ma już metody IsAjaxRequest (), musisz napisać ją samodzielnie, na przykład w Extensions \ HttpRequestExtensions.cs
Szukałem teraz tego przez chwilę i mam nadzieję, że niektórym też pomoże;)
Zasób: https://github.com/aspnet/AspNetCore/issues/2729
źródło
W przypadku aplikacji Ruby on Rails udało mi się zapobiec ładowaniu układu, określając
render layout: false
w akcji kontrolera, że chcę odpowiedzieć za pomocą ajax html.źródło