Поделиться через


Использование AJAX для доставки динамических обновлений

от Майкрософт

Загрузить PDF-файл

Это шаг 10 бесплатного руководства по приложению "NerdDinner" , в которых показано, как создать небольшое, но полное веб-приложение с помощью ASP.NET MVC 1.

Шаг 10 реализует поддержку для вошедшего пользователя в RSVP их интерес к посещению ужина, используя подход на основе Ajax, интегрированный в страницу сведений о ужине.

Если вы используете ASP.NET MVC 3, рекомендуется следовать руководствам по начало работы С MVC 3 или MVC Music Store.

NerdDinner, шаг 10. Включение RSVP ajax принимает

Теперь давайте реализуем поддержку для пользователей, вошедшего в систему, в RSVP их интерес к участию в ужине. Мы включим это с помощью подхода на основе AJAX, интегрированного на странице сведений о ужине.

Указывает, является ли пользователь rsvp'd

Пользователи могут посетить URL-адрес /Dinners/Details/[id], чтобы просмотреть сведения о конкретном ужине:

Снимок экрана веб-страницы Nerd Dinner с подробными сведениями о ужине.

Метод действия Details() реализуется следующим образом:

//
// GET: /Dinners/Details/2

public ActionResult Details(int id) {

    Dinner dinner = dinnerRepository.GetDinner(id);

    if (dinner == null)
        return View("NotFound");
    else
        return View(dinner);
}

Первым шагом для реализации поддержки RSVP будет добавление вспомогательного метода IsUserRegistered(username)" в наш объект Dinner (в разделяемом классе Dinner.cs, который мы создали ранее). Этот вспомогательный метод возвращает значение true или false в зависимости от того, является ли пользователь в настоящее время RSVP'd для ужина:

public partial class Dinner {

    public bool IsUserRegistered(string userName) {
        return RSVPs.Any(r => r.AttendeeName.Equals(userName, StringComparison.InvariantCultureIgnoreCase));
    }
}

Затем можно добавить следующий код в шаблон представления Details.aspx, чтобы отобразить соответствующее сообщение, указывающее, зарегистрирован ли пользователь для события:

<% if (Request.IsAuthenticated) { %>
 
    <% if (Model.IsUserRegistered(Context.User.Identity.Name)) { %>       

        <p>You are registred for this event!</p>
    
    <% } else {  %>  
    
        <p>You are not registered for this event</p>
        
    <% }  %>
    
<% } else { %>
 
    <a href="/Account/Logon">Logon</a> to RSVP for this event.

<% } %>

И теперь, когда пользователь посещает ужин, он регистрируется для, он увидит следующее сообщение:

Снимок экрана: страница сведений о Nerd Dinners, в нижней части отображается сообщение

И когда они посещают ужин, они не зарегистрированы для, они увидят следующее сообщение:

Снимок экрана: страница сведений о Nerd Dinners. Отображается сообщение Вы не зарегистрированы для этого события.

Реализация метода register action

Теперь добавим функциональные возможности, необходимые для предоставления пользователям возможности RSVP на ужин на странице сведений.

Для реализации этого мы создадим класс RSVPController, щелкнув правой кнопкой мыши каталог \Controllers и выбрав команду меню Добавить контроллер>.

Мы реализуем метод действия Register в новом классе RSVPController, который принимает идентификатор для Dinner в качестве аргумента, извлекает соответствующий объект Dinner, проверяет, находится ли вошедший в систему пользователь в настоящее время в списке пользователей, зарегистрированных для него, и, если не добавляет для него объект RSVP:

public class RSVPController : Controller {

    DinnerRepository dinnerRepository = new DinnerRepository();

    //
    // AJAX: /Dinners/RSVPForEvent/1

    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Register(int id) {

        Dinner dinner = dinnerRepository.GetDinner(id);

        if (!dinner.IsUserRegistered(User.Identity.Name)) {
        
            RSVP rsvp = new RSVP();
            rsvp.AttendeeName = User.Identity.Name;

            dinner.RSVPs.Add(rsvp);
            dinnerRepository.Save();
        }

        return Content("Thanks - we'll see you there!");
    }
}

Обратите внимание, что мы возвращаем простую строку в качестве выходных данных метода действия. Мы могли бы внедрить это сообщение в шаблон представления, но так как оно настолько мало, мы просто воспользуемся вспомогательным методом Content() в базовом классе контроллера и возвратим строковое сообщение, как описано выше.

Вызов метода действия RSVPForEvent с помощью AJAX

Мы будем использовать AJAX для вызова метода действия Register из представления Сведений. Реализовать это довольно просто. Сначала мы добавим две ссылки на библиотеку сценариев:

<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

Первая библиотека ссылается на основную ASP.NET библиотеку клиентских скриптов AJAX. Размер этого файла составляет примерно 24 КБ (сжатый) и содержит основные функции AJAX на стороне клиента. Вторая библиотека содержит служебные функции, которые интегрируются со встроенными вспомогательными методами AJAX ASP.NET MVC (которые мы будем использовать в ближайшее время).

Затем можно обновить код шаблона представления, добавленный ранее, чтобы вместо вывода сообщения "Вы не зарегистрированы для этого события" вместо отображения ссылки, которая при отправке выполняет вызов AJAX, который вызывает метод действия RSVPForEvent на контроллере RSVP и RSVP пользователя:

<div id="rsvpmsg">

<% if(Request.IsAuthenticated) { %>
 
    <% if(Model.IsUserRegistered(Context.User.Identity.Name)) { %>       

        <p>You are registred for this event!</p>

    <% } else { %>  
    
        <%= Ajax.ActionLink( "RSVP for this event",
                             "Register", "RSVP",
                             new { id=Model.DinnerID }, 
                             new AjaxOptions { UpdateTargetId="rsvpmsg"}) %>         
    <% } %>
    
<% } else { %>
 
    <a href="/Account/Logon">Logon</a> to RSVP for this event.

<% } %>
    
</div>

Используемый выше вспомогательный метод Ajax.ActionLink() встроен в ASP.NET MVC и похож на вспомогательный метод Html.ActionLink(), за исключением того, что вместо выполнения стандартной навигации он вызывает метод AJAX к методу действия при щелчке по ссылке. Выше мы вызываем метод действия Register для контроллера RSVP и передаваем ему DinnerID в качестве параметра id. Последний передаваемый параметр AjaxOptions указывает, что мы хотим взять содержимое, возвращаемое методом action, и обновить элемент DIV> HTML <на странице с идентификатором "rsvpmsg".

И теперь, когда пользователь переходит на ужин, он еще не зарегистрирован, он увидит ссылку на RSVP для него:

Снимок экрана: страница

Если щелкнуть ссылку "RSVP для этого события", он вызовет AJAX метод действия Register на контроллере RSVP, и по завершении отобразится обновленное сообщение, как показано ниже:

Снимок экрана страницы сведений о Nerd Dinner с сообщением

Пропускная способность сети и трафик, задействованные при выполнении этого вызова AJAX, действительно упрощены. Когда пользователь щелкает ссылку "RSVP для этого события", выполняется небольшой сетевой запрос HTTP POST к URL-адресу /Dinners/Register/1 , который выглядит следующим образом:

POST /Dinners/Register/49 HTTP/1.1
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Referer: http://localhost:8080/Dinners/Details/49

И ответ от нашего метода действия Register будет просто:

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 29
Thanks - we'll see you there!

Этот упрощенный вызов выполняется быстро и будет работать даже в медленной сети.

Добавление анимации jQuery

Реализованная нами функциональность AJAX работает хорошо и быстро. Иногда это может произойти так быстро, что пользователь может не заметить, что ссылка RSVP была заменена новым текстом. Чтобы сделать результат более очевидным, можно добавить простую анимацию, чтобы привлечь внимание к сообщению об обновлении.

Шаблон проекта ASP.NET MVC по умолчанию включает jQuery — отличную (и очень популярную) библиотеку JavaScript открытый код, которая также поддерживается корпорацией Майкрософт. jQuery предоставляет ряд возможностей, в том числе хорошую библиотеку выбора DOM HTML и эффектов.

Чтобы использовать jQuery, сначала добавим в него ссылку на скрипт. Так как мы будем использовать jQuery в различных местах нашего сайта, мы добавим ссылку на скрипт на наш сайт. master master файл подкачки, чтобы его могли использовать все страницы.

<script src="/Scripts/jQuery-1.3.2.js" type="text/javascript"></script>

Код, написанный с помощью JQuery, часто использует глобальный метод JavaScript "$()", который извлекает один или несколько элементов HTML с помощью селектора CSS. Например, $("#rsvpmsg") выбирает любой ЭЛЕМЕНТ HTML с идентификатором rsvpmsg, а $(".something") — все элементы с именем класса CSS "something". Вы также можете создавать более сложные запросы, такие как "вернуть все проверенные переключатели", с помощью запроса селектора, например $("input[@type=radio][@checked]").

После выбора элементов можно вызвать методы для выполнения действий, таких как скрытие: $("#rsvpmsg").hide();

Для нашего сценария RSVP мы определим простую функцию JavaScript с именем "AnimateRSVPMessage", которая выбирает раздел> "rsvpmsg" <и анимирует размер его текстового содержимого. Приведенный ниже код начинает текст с малого, а затем приводит к его увеличению в течение 400 миллисекунд:

<script type="text/javascript">

    function AnimateRSVPMessage() {
        $("#rsvpmsg").animate({fontSize: "1.5em"},400);
    }

</script>

Затем мы можем подключить эту функцию JavaScript к вызову после успешного завершения вызова AJAX, передав ее имя во вспомогательный метод Ajax.ActionLink() (с помощью свойства события AjaxOptions OnSuccess):

<%= Ajax.ActionLink( "RSVP for this event",
                     "Register", "RSVP",
                     new { id=Model.DinnerID }, 
                     new AjaxOptions { UpdateTargetId="rsvpmsg",
                                       OnSuccess="AnimateRSVPMessage"}) %>

И теперь, когда щелкнуть ссылку "RSVP для этого события" и наш вызов AJAX завершится успешно, отправленное обратно сообщение содержимого будет анимироваться и увеличиваться:

Снимок экрана: страница Nerd Dinners с сообщением спасибо, мы увидим вас там крупным шрифтом внизу.

Помимо предоставления события OnSuccess, объект AjaxOptions предоставляет события OnBegin, OnFailure и OnComplete, которые можно обрабатывать (наряду с различными другими свойствами и полезными параметрами).

Очистка — рефакторинг частичного представления RSVP

Наш шаблон представления сведений начинает немного длиннее, что сделает его немного сложнее понять. Чтобы улучшить удобочитаемость кода, давайте создадим частичное представление RSVPStatus.ascx, которое инкапсулирует весь код представления RSVP для страницы сведений.

Это можно сделать, щелкнув правой кнопкой мыши папку \Views\Dinners, а затем выбрав команду меню Добавить-Вид>. Мы получим объект Dinner в качестве строго типизированной модели ViewModel. Затем можно скопировать или вставить в него содержимое RSVP из представления Details.aspx.

После этого давайте создадим еще одно частичное представление — EditAndDeleteLinks.ascx, которое инкапсулирует код представления ссылок Edit и Delete. Мы также получим объект Dinner в качестве строго типизированной модели ViewModel и скопировать или вставить в него логику Edit и Delete из представления Details.aspx.

Наш шаблон представления сведений может включать в себя два вызова метода Html.RenderPartial() в нижней части:

<asp:Content ID="Title" ContentPlaceHolderID="TitleContent"runat="server">
    <%= Html.Encode(Model.Title) %>
</asp:Content>

<asp:Content ID="details" ContentPlaceHolderID="MainContent" runat="server">

    <div id="dinnerDiv">

        <h2><%=Html.Encode(Model.Title) %></h2>
        <p>
            <strong>When:</strong> 
            <%=Model.EventDate.ToShortDateString() %> 

            <strong>@</strong>
            <%=Model.EventDate.ToShortTimeString() %>
        </p>
        <p>
            <strong>Where:</strong> 
            <%=Html.Encode(Model.Address) %>,
            <%=Html.Encode(Model.Country) %>
        </p>
         <p>
            <strong>Description:</strong> 
            <%=Html.Encode(Model.Description) %>
        </p>       
        <p>
            <strong>Organizer:</strong> 
            <%=Html.Encode(Model.HostedBy) %>
            (<%=Html.Encode(Model.ContactPhone) %>)
        </p>
    
        <% Html.RenderPartial("RSVPStatus"); %>
        <% Html.RenderPartial("EditAndDeleteLinks"); %>
 
    </div>
         
</asp:Content>

Это делает код более понятным для чтения и обслуживания.

Следующий шаг

Теперь давайте рассмотрим, как мы можем использовать AJAX еще дальше и добавить поддержку интерактивного сопоставления в наше приложение.