Как стать автором
Обновить

Опыт использования jQuery/AJAX/Telerik Extensions for MVC

Время на прочтение 5 мин
Количество просмотров 5.9K
Недавно занимался портированием проекта с “обычного” ASP.NET на ASP.NET MVC. Решил в силу развития технологий попробовать сделать красиво и асинхронно. Этот пост о том, что и как я писал, и что из этого получилось.

Выбор технологий


Сейчас почему-то все кому не лень переписывают сайты на MVC благо это выглядит изящнее и работает быстрее – последствие феномена Ajax а также всемирного распостранения jQuery. Столкнувшись с такой же задачей (а также весьма сжатыми сроками), я решил тоже попробовать. В плане технологий, я выбрал следующие:
  • Asp.Net MVC и дефолтный ViewEngine. Несмотря на то, что Spark это типа круто, де факто создание “богатого UI” все равно ложится на плечи серверной геренации, так что “красивость тегов” была бы уместна только если я бы генерировал, скажем, обычные таблички вместо Ajax-ориентированных.
  • jQuery. Конечно есть тот же ASP.NET AJAX и интересности вроде Ajax.LinkAction() и т.д., но не имея особого опыта ни в том ни в другом, решил идти на поводу у толпы. Возможно будет время и на то, чтобы изучить варианты от Microsoft.
  • jQuery UI. Супербиблиотечка для jQuery, которая делает весьма красивый пользовательский интерфейс. Мне лично нужен был календарик.
  • Telerik Extensions for ASP.NET MVC для таблиц и tab-контрола. Почему Telerik? Мне понравился простой, понятный API и весьма неплохой по виду интерфейс. Также радует тот факт, что разработчики со статусом MVP получают бесплатные лицензии – у нас в команде из 3х человек таковых двое, так что получается неплохая экономия.
    N.b.: для open source проектов эти компоненты можно использовать бесплатно.

Имея в доступе все компоненты, я приступил к сборке. Ниже я опишу самые ключевые и полезные аспекты, которые смогут пригодиться другим разработчикам.

Работа с таблицами


Главной моей целью при работе со сторонними компонентами было получение асинхронного наполнения таблиц. В принципе, чтобы получить собственно данные для таблицы, нужно вытащить некий IEnumerable<X> и передать его во вьюшку, так? Нет, не совсем.
Если что-то на странице забирает объекты через Ajax, то формат этих объектов должен быть весьма примитивным. Это не то же самое как если бы мы использовали сильнотипизированное представление. Все должно быть весьма примитивно.
Начнем с таблицы как таковой. Таблица (по крайней мере в подходе Telerik) создается с помощью хитрых C# конструктов во вьюшке.

<%= Html.Telerik().Grid<PersonRow>().Name("PersonGrid").Columns(cs =><br/>
{<br/>
  cs.Add(i => i.Name).Title("Name");<br/>
  cs.Add(i => i.Gender).Title("Gender");<br/>
}).Ajax(ajax => ajax.Enabled(true).Action("GetPeople""Home"))<br/>
  .Pageable(pager => pager.PageSize(20).Position(GridPagerPosition.Bottom))<br/>
%><br/>

Код выше определяет таблицу с двумя колонками, при этом для представления он использует не Person (это то что мы получаем из базы), а PersonRow, т.е. модельку которая из Person вытаскивает все что нужно и хранит – угадайте что – просто строки! Потому как никакой дополнительной логики мы добавить в код выше не сможем.
// не транслируется в js, и тем самым не будет работать!<br/>cs.Add(i => i.IsMale ? "Male" : "Female").Title("Gender");<br/>

Так вот, наша табличка асинхронно забирает данные из метода контроллера. Этот метод, естественно, возвращает не IEnumerable<PersonRow> а скромный ActionResult. Дабы все стало понятно, вот чуть-чуть кода:
[GridAction]<br/>
public ActionResult GetPeople()<br/>
{<br/>
  return View(new GridModel<EventRow> {<br/>
    Data = repository.GetPeople().Select(p => new PersonRow(p))<br/>
  });<br/>
}<br/>

Интересно что эти два кусочка кода (на странице и в контроллере) – фактически все, что нужно чтобы асинхронно загружать табличку. Будучи ajax-driven, табличку можно обновлять из того же jQuery. Делается это просто:
$('#PersonGrid').data('tGrid').ajaxRequest();<br/>

Вызов ajax-методов через jQuery


Поскольку я решил использовать jQuery, мне нужно было научиться вызывать методы страниц используя ajax. Мне нужно было и отсылать данные из формы, и получать данные. Для получения данных я воспользовался форматом json, т.е. мои методы на стороне контроллера принимали набор параметров (как обычные controller actions), а возвращали JsonResult.
public JsonResult FindPersonName(string id)<br/>
{<br/>
  try<br/>
  {<br/>
    string name = repository.FindById(int.Parse(id)).Name;<br/>
    return Json(new {Result = Name, Success = true});<br/>
  }<br/>
  catch (Exception ex)<br/>
  {<br/>
    return Json(new {Result = "Could not find person. " + ex.Message, Success = false });<br/>
  }<br/>
}<br/>

Код выше возвращает результат вне зависимости от того, было исключение или нет, что проблематично для нас, т.к. нам нужно обрабатывать целых три разных ситуации:
  • Запрос прошел успешно
  • На стороне сервера было исключение и Success == false
  • До сервера и дело не дошло, ajax-вызов упал на клиенте

Теперь собственно поговорим о вызове этого метода из jQuery. Тут у нас достаточно “пестрый” вызов, который показывает обработку нажатия пользователем на конкретный hyperlink:
$('#lnkFindName').click(function(event) {<br/>
  $.ajax({<br/>
    type: "POST",<br/>
    contentType: "application/x-www-form-urlencoded",<br/>
    url: "/Home/FindPersonName/",<br/>
    dataType: "json",<br/>
    data: {<br/>
      id: $('#personId').val()<br/>
    },<br/>
    success: function(msg, status) {<br/>
      if (msg['Success'] == true) {<br/>
        $('#personName').val(msg['Result']);<br/>
      }<br/>
      else {<br/>
        $('#statusBox').html(msg['Result']).fadeIn();<br/>
      }<br/>
    },<br/>
    error: function(msg, status) {<br/>
      $('#statusBox').html(msg.statusText).fadeIn();<br/>
    }<br/>
  });<br/>
});<br/>

Как видите, json идет в обе стороны, и весьма успешно – получив сообщение, мы вытаскиваем информацию через msg['key']. В примере выше обработаны все три варианта завершения запроса.

Заключение


Должен заметить, что пользоваться инструментарием на основе jQuery – очень просто. И взаимодействие через ajax предельно понятно когда работаешь с грамотно спроектированными компонентами. Как не странно, мой первый ajax-блин комом не вышел. :)
Теги:
Хабы:
+10
Комментарии 9
Комментарии Комментарии 9

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн