Skip to content

5. Додаток кація [SimuPaie] – версія 2 – AJAX / ASP.NET

5.1. Introduction

Технологія AJAX (Asynchronous Javascript And Xml) об’єднує низку технологій:

  • JavaScript: сторінка HTML, що відображається у браузері, може містити код JavaScript. Цей код виконується браузером, якщо користувач не заблокував виконання коду Javascript у своєму браузері. Ця технологія з’явилася ще на початку розвитку Інтернету і з 2005 року знову привертає увагу завдяки AJAX.
  • DOM: Модель об’єктів документа (Document Object Model). Код JavaScript, вбудований у сторінку HTML, має доступ до документа у вигляді дерева об’єктів — DOM. Кожен елемент документа (поле введення, тег <div> з іменем, тег <select> тощо) представлений вузлом дерева. Код JavaScript може змінювати відображуваний документ, модифікуючи DOM. Наприклад, він може змінювати текст, що відображається у полі введення, через вузол DOM, який представляє це поле.

AJAX використовує JavaScript для обміну даними між браузером і сервером у фоновому режимі. У відповідь на подію, таку як натискання кнопки, браузер виконає код JavaScript, щоб надіслати запит HTTP на сервер. Цей запит міститиме параметри, що вказують серверу, що саме він має зробити. Сервер виконає запитувану дію. У відповідь він надішле браузеру потік HTTP, що містить дані, які дозволяють частково оновити сторінку, що зараз відображається. Це буде здійснено за допомогою DOM документа та виконання коду JavaScript, вбудованого в документ. Дані, що повертаються сервером, можуть бути у різних форматах: XML, HTML, JSON, неформатований текст тощо.

Перевага цієї технології полягає саме в такому частковому оновленні відображуваного документа. Це означає:

  • менший обмін даними між клієнтом і сервером, а отже, швидшу відповідь
  • більш плавний графічний інтерфейс, оскільки дії користувача не призводять до повного перезавантаження сторінки.

В інтранеті, де мережевий обмін даними відбувається швидко, AJAX дозволяє створювати веб-додатки, поведінка яких наближається до поведінки класичних інтерфейсів Windows. Дійсно, можна обробляти такі події, як зміна вибору у списку, та негайно й частково оновлювати сторінку, щоб відобразити цю зміну вибору. Те, що сторінка не перезавантажується повністю, створює у користувача враження плавності роботи, звичне для додатків Windows. Для інтернет-додатків, де час відгуку може бути тривалим, технологія AJAX залишається придатною для використання, але враження плавності залежить від швидкості мережі.

Головною складністю в AJAX є мова JavaScript. Створена ще на початку розвитку Інтернету,

  • він виявляється малопридатним для об’єктно-орієнтованого програмування. Наприклад, це не типізована мова. У ній не вказується тип даних, з якими працюють. У цьому вона нагадує такі мови, як Perl або PHP.
  • У нього немає стандарту, прийнятого всіма браузерами. Кожен із них має власні розширення «JavaScript», через що код JavaScript, написаний для IE, може не працювати в Mozilla Firefox і навпаки.
  • Його важко налагоджувати, оскільки браузери не пропонують ефективних інструментів для налагодження коду JavaScript, який вони виконують.

Усі ці недоліки JavaScript призвели до того, що до появи AJAX він майже не використовувався. Зрозумівши переваги виконання коду JavaScript у фоновому режимі для надсилання запитів HTTP до веб-сервера та використання його відповіді для за допомогою DOM, часткове оновлення відображуваного документа, команди розробників взялися до роботи та запропонували фреймворки, що дозволяють виконувати AJAX без необхідності написання коду JavaScript розробником. Для цього були написані бібліотеки JavaScript, які вміють адаптуватися до клієнтського браузера. Вставлення коду JavaScript у сторінку HTML, що надсилається до браузера, відбувається на стороні сервера за допомогою технік, які відрізняються залежно від використовуваного фреймворку AJAX. Існують фреймворки Ajax як для Java, .NET, PHP, так і для Ruby, ... AJAX інтегровано у Visual Web Developer 2008.

5.2. Проєкт Visual Web Developer на рівні [web-ui-ajax]

Нову версію отримують шляхом дублювання попередньої версії. Змінюватиметься лише сторінка [Default.aspx].

  • у [1]: за допомогою Провідника Windows дублюємо папку проєкту [pam-v1-adonet] і надаємо їй ім’я [pam-v2-adonet-ajax]. Потім за допомогою Visual Web Developer відкриваємо проект (Файл / Відкрити проект) із цієї нової папки [2]
  • у [3], надаємо йому нову назву
  • у властивостях нового проєкту змінюємо назву збірки [4], а також простір імен за замовчуванням на [5].

Після цього у файлах [Default.aspx, Default.aspx.cs, Default.aspx.designer.cs, Global.asax, Global.asax.cs] замінюємо простір імен [pam_v1] на простір імен [pam_v2], щоб забезпечити узгодженість із простором імен за замовчуванням. Наприклад, [Default.aspx] [6] стає:


<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="pam_v2._Default" %>
...

Сторінка [Default.aspx] буде змінена наступним чином:

  • додавання компонентів Ajax у форму [Default.aspx] (див. [2] вище).
    • 2A: компонент <asp:ScriptManager> необхідний для будь-якого проєкту AJAX
    • 2B: компонент <asp:UpdatePanel> слугує для визначення області, яку потрібно оновити під час дії користувача POST. Цей компонент запобігає повному перезавантаженню сторінки.
    • 2C: компонент <asp:UpdateProgress> використовується для відображення тексту або зображення під час оновлення, щоб попередити користувача, як показано нижче:
  • (продовження)
    • 2D: тип Label із назвою LabelHeureLoad, який відображатиме час виконання обробника події Load на сторінці.
    • 2E: тип Label з іменем LabelHeureSalaire, який відображатиме час виконання обробника події Click для кнопки [Salaire]. Ми хочемо показати, що Ajax не перезавантажує всю сторінку під час натискання кнопки [Salaire]. Це ілюструє попередній знімок екрана, на якому можна побачити два різних часових значення у двох Labels.

Попередню «аджаксифікацію» форми можна здійснити безпосередньо у вихідному коді [Default.aspx] шляхом додавання тегів розширень 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>
          &nbsp;</asp:Panel>
      </ContentTemplate>
    </asp:UpdatePanel>
  </form>
</body>
</html>
  • рядок 8: будь-яка форма, адаптована до Ajax, повинна містити тег <asp:ScriptManager>. Саме цей тег дозволяє використовувати нові компоненти Ajax:
  • тег <asp:ScriptManager> можна отримати, двічі клацнувши на компоненті [ScriptManager], показаному вище. Необхідно переконатися, що цей тег міститься в тезі <form> вихідного коду. Атрибут [EnablePartialRendering= "true "] у рядку 8 за замовчуванням відсутній. Оскільки його значенням за замовчуванням є «true», він не є обов’язковим.
  • рядок 9: тег <asp:UpdatePanel> дозволяє виділити області сторінки, які мають бути оновлені під час часткового оновлення сторінки. Атрибут [UpdateMode="Conditional"] вказує, що область має оновлюватися лише при виникненні події AJAX у компоненті цієї області. Інше значення — [UpdateMode="Always"] — є значенням за замовчуванням. З цим атрибутом область UpdatePanel оновлюється систематично, навіть якщо подія Ajax, що відбулася, походить від компонента іншої області UpdatePanel. Як правило, така поведінка є небажаною.

Тег <asp:UpdatePanel> підтримує два дочірні теги: <ContentTemplate> та <Triggers>.

  • Теги <asp:ContentTemplate> (рядки 10 і 53) обмежують область сторінки, яку потрібно частково оновити.
  • рядки 27–33: компонент Ajax <asp:UpdateProgress>, що дозволяє відображати текст протягом усього часу оновлення сторінки. Наприклад, натискання кнопки [Salaire] спричинить виконання POST у фоновому режимі. У цей час браузер не відображає пісочний годинник, тому користувач може спробувати продовжити роботу з формою. Тег <asp:UpdateProgress> дозволяє відображати текст, що попереджає про те, що триває оновлення сторінки. Також можна відображати зображення. Тут відображається анімоване зображення (рядок 29), а також текст (рядки 30–31):
 
  • рядки 28–32: тег <ProgressTemplate> обмежує вміст, який буде відображатися протягом усього часу оновлення зони UpdatePanel, у якій знаходиться тег UpdateProgress.
  • рядки 29–31: анімоване зображення та текст, які будуть відображатися під час оновлення зони UpdatePanel.
  • рядок 5: мітка LabelHeureLoad розміщується поза зоною, що оновлюється за допомогою AJAX
  • рядок 34: мітка LabelHeureSalaire розміщується в зоні, що оновлюється за допомогою AJAX

Код сторінки [Default.aspx.cs] змінюється наступним чином:


    protected void Page_Load(object sender, System.EventArgs e)
    {
        // час кожного завантаження сторінки
        LabelHeureLoad.Text = DateTime.Now.ToString("hh:mm:ss");
        // обробка початкового запиту
        if (!IsPostBack)
        {
....
}
  • рядок 4: оновлення часу завантаження сторінки

   protected void ButtonSalaire_Click(object sender, System.EventArgs e)
    {
        // час розрахунку заробітної плати
        LabelHeureSalaire.Text = DateTime.Now.ToString("hh:mm:ss");
        // перевіряються дані
....
}
  • рядок 4: оновлення часу розрахунку заробітної плати

Щоб завершити сторінку [Default.aspx], нам потрібно включити анімований малюнок, на який посилається рядок 4 у наступному вихідному коді сторінки:


            <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>

За допомогою Провідника Windows додаємо файл [images/indicator.gif] до папки проєкту [1]:

  • у [2] переглядаємо всі файли проєкту
  • у [3], папку [images]
  • в [4] додаємо папку [images] до проекту
  • у [5] папка [images] була включена до проекту
  • у [6] приховано файли, що не входять до складу проекту
  • у [7] — новий проєкт

5.3. Тестування рішення Ajax

При запуску проекту (CTRL-F5) відкривається така сторінка:

  • у [1] — час завантаження сторінки

Проведіть тестування та переконайтеся, що кнопка [Salaire] не спричиняє повного перезавантаження сторінки. Це можна побачити за часом, що відображається для обробки кліка на кнопку [Salaire] [2], який не збігається з часом початкового завантаження сторінки [3]:

Повторіть тести, змінивши властивість EnablePartialRendering компонента ScriptManager1 на False:

  

Переконатися, що в цьому випадку сторінка поводиться як сторінка без використання AJAX. При натисканні на кнопку [Salaire] відбувається повне перезавантаження сторінки. Повторіть тести в іншому браузері. Мета тестування в різних браузерах — продемонструвати, що JavaScript-код, згенерований серверними компонентами ASP / AJAX, правильно інтерпретується різними браузерами.

Наостанок звернемо увагу на роль тегу <asp:UpdateProgress>. У коді процедури [ButtonSalaire_Click] з [Default.aspx.cs] додамо інструкцію, яка зупиняє процедуру на 3 секунди:


using System.Threading;
   ...
protected void ButtonSalaire_Click(object sender, System.EventArgs e)
    {
        // час розрахунку заробітної плати
        LabelHeureSalaire.Text = DateTime.Now.ToString("hh:mm:ss");
        // очікування 
        Thread.Sleep(3000);
        // перевірка даних
....
}

У рядку 8 потік, що виконує процедуру [ButtonSalaire_Click], очікує 5 секунд. Зробивши це, повторімо тести (після того, як знову встановимо атрибут EnablePartialRendering компонента ScriptManager1 у значення True). Цього разу під час розрахунку заробітної плати ми бачимо текст [UpdateProgress], а також анімоване зображення:

Image

5.4. Conclusion

Попереднє дослідження показало, що існуючі додатки ASP.NET можна адаптувати до AJAX. Розширення AJAX до ASP.NET виходять за межі того, що ми щойно розглянули. Читачам пропонується відвідати сайт [http://ajax.asp.net].