5. Aplikacj cja [SimuPaie] – wersja 2 – AJAX / ASP.NET
5.1. Introduction
Technologia AJAX (Asynchronous JavaScript and XML) łączy w sobie szereg technologii:
- JavaScript: strona HTML wyświetlana w przeglądarce może zawierać kod JavaScript. Kod ten jest wykonywany przez przeglądarkę, o ile użytkownik nie zablokował wykonywania kodu JavaScript w swojej przeglądarce. Technologia ta pojawiła się już w początkach internetu, a od 2005 roku cieszy się ponownym zainteresowaniem dzięki AJAX.
- DOM: Model obiektowy dokumentu (Document Object Model). Kod JavaScript osadzony na stronie HTML ma dostęp do dokumentu w postaci drzewa obiektów, czyli DOM. Każdy element dokumentu (pole wprowadzania danych, tag <div> o określonej nazwie, tag <select> itp.) jest reprezentowany przez węzeł drzewa. Kod JavaScript może zmieniać wyświetlany dokument poprzez modyfikację drzewa DOM. Na przykład może on zmieniać tekst wyświetlany w polu wprowadzania danych za pośrednictwem węzła drzewa DOM reprezentującego to pole.
AJAX wykorzystuje JavaScript do wymiany danych między przeglądarką a serwerem w tle. W odpowiedzi na zdarzenie, takie jak kliknięcie przycisku, przeglądarka wykona kod JavaScript w celu wysłania żądania HTTP do serwera. Żądanie to będzie zawierało parametry wskazujące serwerowi, co ma wykonać. Serwer wykona żądaną czynność. W odpowiedzi serwer wyśle do przeglądarki strumień HTTP zawierający dane umożliwiające częściową aktualizację aktualnie wyświetlanej strony. Zostanie to zrealizowane za pośrednictwem elementu DOM w dokumencie oraz poprzez wykonanie kodu JavaScript osadzonego w dokumencie. Dane zwracane przez serwer mogą mieć różne formaty: XML, HTML, JSON, tekst nieformatowany itp.
Zaletą tej technologii jest właśnie częściowa aktualizacja wyświetlanego dokumentu. Oznacza to:
- mniej danych wymienianych między klientem a serwerem, a tym samym szybszą odpowiedź
- bardziej płynny interfejs graficzny, ponieważ działania użytkownika nie powodują całkowitego przeładowania strony.
W intranecie, gdzie komunikacja sieciowa przebiega szybko, AJAX pozwala tworzyć aplikacje internetowe, których działanie przypomina klasyczne interfejsy systemu Windows. Można bowiem obsługiwać zdarzenia, takie jak zmiana wyboru na liście, i natychmiastowo, częściowo odświeżyć stronę, aby odzwierciedlić tę zmianę. Fakt, że strona nie jest całkowicie odświeżana, daje użytkownikowi wrażenie płynności działania, jakie zna z aplikacji systemu Windows. W przypadku aplikacji internetowych, gdzie czasy odpowiedzi mogą być długie, technologia AJAX pozostaje użyteczna, ale wrażenie płynności zależy od wydajności sieci.
Główną trudnością w AJAX jest język JavaScript. Stworzony już na początku istnienia sieci WWW,
- okazuje się mało praktyczny do programowania obiektowego. Nie jest to na przykład język typowany. Nie deklaruje się w nim typu przetwarzanych danych. Pod tym względem przypomina języki takie jak Perl czy PHP.
- Nie ma standardu akceptowanego przez wszystkie przeglądarki. Każda z nich posiada własne, zastrzeżone rozszerzenia „JavaScript”, co powoduje, że kod JavaScript napisany dla IE może nie działać w przeglądarce Mozilla Firefox i odwrotnie.
- Trudno go debugować, ponieważ przeglądarki nie oferują wydajnych narzędzi do debugowania kodu JavaScript, który wykonują.
Wszystkie te niedociągnięcia języka JavaScript sprawiły, że przed pojawieniem się AJAX był on rzadko stosowany. Gdy zrozumiano korzyści płynące z uruchamiania kodu JavaScript w tle w celu wysyłania zapytań HTTP do serwera WWW i wykorzystywania jego odpowiedzi do dzięki DOM, częściowej aktualizacji wyświetlanego dokumentu, zespoły programistów zabrały się do pracy i zaproponowały frameworki umożliwiające realizację AJAX bez konieczności pisania kodu JavaScript przez programistę. W tym celu napisano biblioteki JavaScript, które potrafią dostosować się do przeglądarki klienta. Wstawianie kodu JavaScript do strony HTML wysyłanej do przeglądarki odbywa się po stronie serwera, zgodnie z technikami różniącymi się w zależności od używanego frameworka AJAX. Istnieją frameworki Ajax zarówno dla Javy, .NET, PHP, Ruby, ... AJAX jest zintegrowany z programem Visual Web Developer 2008.
5.2. Projekt Visual Web Developer warstwy [web-ui-ajax]
Nową wersję uzyskuje się poprzez skopiowanie poprzedniej wersji. Zmianie ulegnie jedynie strona [Default.aspx].
![]() |
- w [1]: za pomocą Eksploratora Windows duplikujemy folder projektu [pam-v1-adonet] i nadajemy mu nazwę [pam-v2-adonet-ajax]. Następnie w programie Visual Web Developer otwieramy projekt (Plik / Otwórz projekt) z tego nowego folderu [2]
- jako [3] i nadajemy mu nową nazwę
![]() |
- w właściwościach nowego projektu zmieniamy nazwę zestawu [4] oraz domyślną przestrzeń nazw na [5].
Po wykonaniu tych czynności w plikach [Default.aspx, Default.aspx.cs, Default.aspx.designer.cs, Global.asax, Global.asax.cs] zastępujemy przestrzeń nazw [pam_v1] przestrzenią nazw [pam_v2], aby zachować spójność z domyślną przestrzenią nazw. Na przykład [Default.aspx] [6] zmienia się na:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="pam_v2._Default" %>
...
Strona [Default.aspx] zostanie zmodyfikowana w następujący sposób:
![]() |
- dodanie komponentów Ajax do formularza [Default.aspx] (patrz [2] powyżej).
- 2A: komponent <asp:ScriptManager> jest niezbędny dla każdego projektu AJAX
- 2B: komponent <asp:UpdatePanel> służy do wyznaczenia obszaru, który ma zostać odświeżony w wyniku akcji użytkownika POST. Komponent ten pozwala uniknąć całkowitego przeładowania strony.
- 2C: komponent <asp:UpdateProgress> służy do wyświetlania tekstu lub obrazu na czas trwania aktualizacji, aby poinformować o tym użytkownika, jak pokazano poniżej:
![]() |
- (ciąg dalszy)
- 2D: typ Label o nazwie LabelHeureLoad, który wyświetli godzinę wykonania procedury obsługi zdarzenia Load na stronie.
- 2E: typ Label o nazwie LabelHeureSalaire, który wyświetli godzinę uruchomienia obsługi zdarzenia Click dla przycisku [Salaire]. Chcemy pokazać, że Ajax nie odświeża całej strony po kliknięciu przycisku [Salaire]. Pokazuje to poprzedni zrzut ekranu, na którym widać dwie różne godziny w obu elementach Labels.
Wcześniejsze dostosowanie formularza do technologii Ajax można przeprowadzić bezpośrednio w kodzie źródłowym [Default.aspx] poprzez dodanie tagów rozszerzeń Ajax:
...
<body style="text-align: left" bgcolor="#ffccff">
<h3>
Feuille de salaire
<asp:Label ID="LabelHeureLoad" runat="server" BackColor="#C0C000"></asp:Label></h3>
<hr />
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" />
<asp:UpdatePanel runat="server" ID="UpdatePanelPam" UpdateMode="Conditional">
<ContentTemplate>
<div>
<table>
<tr>
...
<tr>
<td>
<asp:DropDownList ID="ComboBoxEmployes" runat="server">
</asp:DropDownList></td>
<td>
<asp:TextBox ID="TextBoxHeures" runat="server" EnableViewState="False">
</asp:TextBox></td>
<td>
<asp:TextBox ID="TextBoxJours" runat="server" EnableViewState="False">
</asp:TextBox></td>
<td>
<asp:Button ID="ButtonSalaire" runat="server" Text="Salaire" CausesValidation="False" /></td>
<td> <asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
<img src="images/indicator.gif" />
<asp:Label ID="Label5" runat="server" BackColor="#FF8000" EnableViewState="False"
Text="Calcul en cours. Patientez ...."></asp:Label>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:Label ID="LabelHeureSalaire" runat="server" BackColor="#C0C000"></asp:Label></td>
</tr>
<tr>
...
</tr>
</table>
</div>
<br />
....
<table>
<tr>
<td>
Salaire net à payer :
</td>
<td align="center" bgcolor="#C0C000" height="20px">
<asp:Label ID="LabelSN" runat="server" EnableViewState="False"></asp:Label></td>
</tr>
</table>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>
- wiersz 8: każdy formularz z obsługą Ajaxu musi zawierać tag <asp:ScriptManager>. To właśnie ten tag umożliwia korzystanie z nowych komponentów Ajax:
![]() |
- tag <asp:ScriptManager> można uzyskać, klikając dwukrotnie powyższy komponent [ScriptManager]. Należy upewnić się, że ten tag znajduje się w tagu <form> w kodzie źródłowym. Atrybut [EnablePartialRendering= "true "] w wierszu 8 jest domyślnie nieobecny. Ponieważ jego wartością domyślną jest „true”, nie jest on niezbędny.
- wiersz 9: tag <asp:UpdatePanel> pozwala wyznaczyć obszary strony, które mają zostać zaktualizowane podczas częściowej aktualizacji strony. Atrybut [UpdateMode="Conditional"] wskazuje, że obszar ten powinien zostać zaktualizowany wyłącznie w przypadku wystąpienia zdarzenia AJAX w komponencie należącym do tego obszaru. Inną wartością jest [UpdateMode="Always"] i jest to wartość domyślna. Dzięki temu atrybutowi obszar UpdatePanel jest aktualizowany systematycznie, nawet jeśli zdarzenie Ajax, które miało miejsce, pochodzi z komponentu innego obszaru UpdatePanel. Zazwyczaj takie zachowanie nie jest pożądane.
Tag <asp:UpdatePanel> dopuszcza dwa tagi potomne: <ContentTemplate> i <Triggers>.
- Tagi <asp:ContentTemplate> w wierszach 10 i 53 wyznaczają obszar strony, który ma zostać częściowo zaktualizowany.
- wiersze 27–33: komponent Ajax <asp:UpdateProgress>, umożliwiający wyświetlanie tekstu przez cały czas trwania aktualizacji strony. Na przykład kliknięcie przycisku [Salaire] spowoduje uruchomienie POST w tle. Przeglądarka nie wyświetla wówczas ikony klepsydry, co może skłonić użytkownika do dalszego korzystania z formularza. Tag <asp:UpdateProgress> pozwala wyświetlić tekst informujący, że trwa aktualizacja strony. Można również wyświetlić obraz. W tym przypadku wyświetlany jest animowany obraz (wiersz 29) oraz tekst (wiersze 30–31):
![]() |
- wiersze 28–32: tag <ProgressTemplate> wyznacza zawartość, która będzie wyświetlana przez cały czas trwania aktualizacji strefy UpdatePanel, w której znajduje się tag UpdateProgress.
- wiersze 29–31: animowany obraz i tekst, które będą wyświetlane podczas aktualizacji obszaru UpdatePanel.
- wiersz 5: etykieta LabelHeureLoad jest umieszczona poza strefą obsługiwanej przez AJAX
- wiersz 34: etykieta LabelHeureSalaire jest umieszczana w obszarze obsługiwanym przez AJAX
Kod strony [Default.aspx.cs] zmienia się natomiast w następujący sposób:
protected void Page_Load(object sender, System.EventArgs e)
{
// czas każdego załadowania strony
LabelHeureLoad.Text = DateTime.Now.ToString("hh:mm:ss");
// przetwarzanie pierwszego żądania
if (!IsPostBack)
{
....
}
- wiersz 4: aktualizacja czasu załadowania strony
protected void ButtonSalaire_Click(object sender, System.EventArgs e)
{
// czas obliczenia wynagrodzenia
LabelHeureSalaire.Text = DateTime.Now.ToString("hh:mm:ss");
// sprawdzanie danych
....
}
- wiersz 4: aktualizacja godziny obliczenia wynagrodzenia
Aby ukończyć stronę [Default.aspx], musimy dołączyć animowany obraz, do którego odwołuje się wiersz 4 poniższego kodu źródłowego strony:
<td>
<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
<img src="images/indicator.gif" />
<asp:Label ID="Label5" runat="server" BackColor="#FF8000" EnableViewState="False"
Text="Calcul en cours. Patientez ...."></asp:Label>
</ProgressTemplate>
</asp:UpdateProgress>
<asp:Label ID="LabelHeureSalaire" runat="server" BackColor="#C0C000"></asp:Label>
</td>
Za pomocą Eksploratora Windows dodajemy plik [images/indicator.gif] do folderu projektu [1]:
![]() |
- w [2] wyświetlamy wszystkie pliki projektu
- w [3], folder [images]
- w [4], dodajemy folder [images] do projektu
![]() |
- do [5], folder [images] został dołączony do projektu
- w [6] ukryto pliki, które nie są częścią projektu
- w [7], nowy projekt
5.3. Testy rozwiązania Ajax
Po uruchomieniu projektu (CTRL-F5) wyświetla się następująca strona:
![]() |
- w [1] – czas ładowania strony
Przeprowadź testy i sprawdź, czy przycisk [Salaire] nie powoduje całkowitego przeładowania strony. Można to zaobserwować na podstawie czasu wyświetlanego dla przetworzenia kliknięcia przycisku [Salaire] [2], który nie jest taki sam jak czas pierwotnego załadowania strony [3]:
![]() |
Powtórz testy, zmieniając właściwość EnablePartialRendering komponentu ScriptManager1 na False:
![]() |
Zauważ, że wówczas strona zachowuje się tak, jakby nie korzystała z AJAX. Po kliknięciu przycisku [Salaire] następuje całkowite odświeżenie strony. Powtórz testy w innej przeglądarce. Test w wielu przeglądarkach ma na celu wykazanie, że kod JavaScript generowany przez komponenty serwerowe ASP / AJAX jest poprawnie interpretowany przez różne przeglądarki.
Na koniec zwróćmy uwagę na rolę tagu <asp:UpdateProgress>. W kodzie procedury [ButtonSalaire_Click] należącej do [Default.aspx.cs] dodajmy instrukcję, która zatrzymuje procedurę na 3 sekundy:
using System.Threading;
...
protected void ButtonSalaire_Click(object sender, System.EventArgs e)
{
// czas obliczenia wynagrodzenia
LabelHeureSalaire.Text = DateTime.Now.ToString("hh:mm:ss");
// oczekiwanie
Thread.Sleep(3000);
// sprawdzanie danych
....
}
Wiersz 8 powoduje, że wątek wykonujący procedurę [ButtonSalaire_Click] czeka 5 sekund. Po wykonaniu tej czynności przeprowadźmy ponownie testy (po przywróceniu atrybutu EnablePartialRendering komponentu ScriptManager1 do wartości True). Tym razem podczas obliczania wynagrodzenia widoczny jest tekst z procedury [UpdateProgress] oraz animowany obraz:

5.4. Conclusion
Poprzednia analiza wykazała, że możliwe jest wdrożenie technologii AJAX w istniejących aplikacjach ASP.NET. Rozszerzenia AJAX do ASP.NET wykraczają poza to, co właśnie omówiono. Zachęcamy czytelnika do odwiedzenia strony [http://ajax.asp.net].










