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.
