Niedawno brałem udział w hackathonie DevMuster organizowanym w PJATK. Tematyka obejmowała tworzenie rozwiązań w dwóch kategoriach: dla studentów i dla seniorów. Mój team postawił na aplikację łączącą seniorów chcących dzielić się wiedzą z juniorami szukających jakichś informacji.
Początkowo chcieliśmy pracować w Django, ale moja znajomość Pythona jest znikoma, więc po 3 godzinach wywaliliśmy cały projekt i zaczęliśmy od nowa w ASP.NET MVC. Trochę się pomęczyliśmy, ja zdobyłem nowe doświadczenia z Entity Framework, no i wyszło coś takiego.
A gdzie AJAX?
Postanowiłem pobawić się w częściowe widoki (Partial Views) i za pomocą AJAXa pobierałem markup z kontrolera, a następnie wszczepiałem w odpowiedni <div>
na stronie przy pomocy jQuery. Robiłem to dość manualnie. Dopiero potem odkryłem wbudowane rozwiązanie w ASP.NET.
Przy czym trochę się napracowałem, żeby działało. Istnieje paczka NuGetowa Microsoft jQuery Unobtrusive Ajax, która zapewnia niezbędne pliki JavaScript. Niestety z nie znanych mi powodów Visual Studio nie przekopiowało ich do folderu ~/Scripts
, więc musiałem zrobić to ręcznie. Tak samo musiałem ręcznie dodać je do widoku.
Jak to wygląda od strony klas?
Jeszcze nie rozgryzłem struktury klas w ASP.NET, ale większość rzeczy związanych z widokami opiera się o ,,Helpery”. Do nich należy AjaxHelper
, który został rozszerzony w klasie AjaxExtensions
o następujące metody:
ActionLink()
- wypisuje<a>
z odnośnikiem to podanej akcji. Po kliknięciu zapytanie zostanie obsłużone asynchronicznie przez JavaScript.RouteLink()
- jak wyżej, ale zamiast podawać akcji podajemy wirtualny URL.BeginForm()
- wypisuje<form>
z odpowiednimi parametrami. Po kliknięciu w przycisk typu"submit"
wysyła asynchroniczne zapytanie z parametrami z formularza.BeginRouteForm()
- jak wyżej, ale zamiast podawać akcji podajemy wirtualny URL.GlobalizationScript()
- wypisuje<script>
zawierający odnośnik do skryptu z informacjami o globalizacji.
Prawie każdy z powyższych (oprócz ostatniego) zawiera parametr typu AjaxOptions
, który definiuje następujące parametry:
public class AjaxOptions
{
public AjaxOptions();
public IDictionary<string, object> ToUnobtrusiveHtmlAttributes();
public string Confirm { get; set; }
public string HttpMethod { get; set; }
public InsertionMode InsertionMode { get; set; }
public int LoadingElementDuration { get; set; }
public string LoadingElementId { get; set; }
public string OnBegin { get; set; }
public string OnComplete { get; set; }
public string OnFailure { get; set; }
public string OnSuccess { get; set; }
public string UpdateTargetId { get; set; }
public string Url { get; set; }
public bool AllowCache { get; set; }
}
Parametry z przedrostkiem On
to nazwy funkcji JavaScriptowych, które mają zostać wywołane w odpowiedzi na dany event.
Confirm
określa wiadomość jaką dostanie użytkownik do potwierdzenia przed wysłaniem żądania.
InsertionMode
to enum, który określa co zrobić z odpowiedzią. Możliwe jest Replace
, InsertBefore
oraz InsertAfter
(jest też opcja ReplaceWith
, które jest bardziej zgodna z jQuery mimo, że Microsoft domyślnie używa Replace
). Dotyczy to obiektu, którego ID możemy zdefiniować w UpdateTargetId
(domyślnie jest to wstawiony element).
A LoadingElementDuration
określa czas animacji chowania/pokazywania obiektu ładowania, na który wskazuje LoadingElementId
.
Przykład
<div id="messages"></div>
@using (Ajax.BeginForm("AjaxTest",
new AjaxOptions
{
Confirm = "Czy napewno chcesz wysłać wiadomość?",
HttpMethod = "Post",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "messages",
OnComplete = "ajaxComplete"
}))
{
@Html.Label("message", "Wiadomość");
@Html.TextArea("message");
<button type="submit">Wyslij</button>
}
W powyższym przykładzie wysyłamy message
w zapytaniu POST do akcji "AjaxTest"
, a to co otrzymamy dopisujemy na końcu do DIVa ,,messages”.
Cały przykładowy projekt możesz pobrać z mojego Githuba.