Pull to refresh

Динамические данные в jQuery Mobile с помощью jQuery Templates

Reading time6 min
Views5K

Введение


Вышла уже четвертая альфа jQuery Mobile, сделавшая фреймворк более-менее стабильным и удобным в использовании. Единственное, чего пока сильно не хватает — хорошей документации. Например, сейчас там описан только стандартный workflow показывающий переходы по JQM страницам. Но что делать, если вы хотите загружать данные динамически?
Статья подразумевает, что у вас есть хотя бы небольшие представления о том, что такое javascript, как работает jQuery и JQM.

Инструменты


Итак, задача простая: забрать данные с помощью XHR и показать их пользователю. Для начала попробуем посмотреть, что есть в нашем распоряжении. Это jQuery и jQuery Mobile, который по сути является расширением jQuery, адаптирующим контент для мобильных устройств. Самый простой вариант будет выглядеть как-то так:
$.get('/data/url', function(data){
    for(var item in data){
        $("#content").append("<p>"+item+"</p>");
    }
});

И хотя в данном примере все просто, на деле этот подход потребует кучу усилий, строк кода, и поэтому не является лучшим вариантом. Было бы гораздо проще, если бы мы могли просто отдать подлученные данные какой-то функции, показать темплейт и получить красивый HTML. И тут нам на помощь приходят jQuery Templates, ведь именно это они и делают.

Пробуем


Итак, попробуем написать страницу, которая будет динамически получать какие-нибудь данные и показывать их нам с помощью JQM. Чтобы не писать свой сервер-функции-API, возьмем пример из документации по функции $.getJSON(), который забирает данные из Flickr'а и выглядит следующим образом:
$.getJSON("api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
  {
    tags: "cat",
    tagmode: "any",
    format: "json"
  },
  function(data) {
    $.each(data.items, function(i,item){
      $("<img/>").attr("src", item.media.m).appendTo("#images");
      if ( i == 3 ) return false;
    });
  });

Конечно, все что находится внутри function(data){} нам не нужно, мы будем менять это на темплейты.

Готовим площадку

Для начала посмотрим, что приходит от сервиса с помощью console.log(data). Ниже приведен сокращенный листинг интересущей нас части.
Object
  generator: "http://www.flickr.com/"
  items: Array[20]
    0: Object
      author: "nobody@flickr.com (e m i m i)"
      description: " <p><a href="http://www.flickr.com/people/emimi/">e m i m i</a> posted a photo:</p> <p><a href="http…"
      link: "http://www.flickr.com/photos/emimi/5587960723/"
      media: Object
          m: "http://farm6.static.flickr.com/5307/5587960723_7d9c0a7a25_m.jpg"
      tags: "cat romeo 貓 羅密歐 囉咪歐"

Получается, что есть массив items, в котором и лежат интересующие нас данные. Скажем, мы хотим сделать список с превьюшками картинок. Тогда каждый элемент из массива должен будет находиться внутри тега <li> и темплейт будет выглядеть примерно как показано в листинге ниже.
<script id="dataTemplate" type="text/x-jquery-tmpl">
    <li role="option">
        <a href="#">
            <img src="${media.m}" >
            <h3>${ $(description).text() }</h3>
            <p>${tags}</p>
        </a>
    </li>
</script>

Данный темплейт будет выводить превью картинки из Flickr'а, описание как главные текст и теги как подтекст. Стоит отметить, что jQuery Templates является очень мощной библиотекой, позволяющей примернять саму jQuery внутри своих темплейтов, например очищять описание от тегов, как это сделано в предыдщуем листинге.

Добавляем основну

Теперь надо добавить на страницу кнопку, по нажатию на которую будет происходить вся магия, и наш пустой список, который будет заполняться данными. Выглядеть это будет как-то так:
<div data-role="content"> 
    <a href="#" data-role="button" data-theme="b" id="load-data">Load data</a>
    <ul data-role="listview" data-inset="true" id="data-listholder"></ul>
</div> 

И чтобы все это работало, добавляем немного javascript. Объяснения, как оно работает, чуть ниже.
  1.     // do all stuff on document ready
  2.     $(document).ready(function(){     
  3.         $("#load-data").click(function(){
  4.             // show loading indicator
  5.             $.mobile.pageLoading();
  6.  
  7.             $.getJSON("api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
  8.             {
  9.                 tags: "cat",
  10.                 tagmode: "any",
  11.                 format: "json"
  12.             },
  13.             function(data) {
  14.                 // render data into templates and append to list
  15.                 $("#dataTemplate").tmpl(data.items).appendTo("#data-listholder");
  16.                 // refresh list view
  17.                 $("#data-listholder").listview("refresh");
  18.                 // hide loading indicator
  19.                 $.mobile.pageLoading(true);
  20.             });
  21.         });
  22.     });

Строки 1-3 вам должны быть уже знакомы — после загрузки страницы мы вешаем event listener на нашу кнопку на нажатие. По нажатию происходит следующее: сначала функция pageLoading() показывает красивый индикатор загрузки. Потом происходит запрос к Flickr'у, который получает наши данные. После получения данных, с помощью jQuery выбирается элемент DOM, содержащий наш темплейт и используется функция tmpl(), которая с помощью этого темплейта создает HTML на база массива items из полученных данных. Созданный HTML с помощью append() добавляется к нашему пустому списку. Если просто добавить данные к списку, то мы получим довольно некрасивый HTML (можете попробовать закомментировать строку 17 в js коде и запросить данные), потому что jQuery Mobile отрисовывает все после загрузки страницы, либо по запросу скрипта. Поэтому мы должны сказать, что хотим обновить наш список с помощью listview('refresh'). После этого, с помощью функции pageLoading(true) прячется индикатор загрузки. И мы видим (в данном случае не совсем) аккуратный список.
Вот и все, мы динамически загрузили и показали данные с помощью jQuery Mobile

Заключение


Полный исходный код может быть найден на GitHub'е. Подробное описание jQuery Templates можно найти на сайте jQuery в соответствующем разделе. Вопросы можно и нужно задавать, постараюсь ответить на все.
Tags:
Hubs:
+27
Comments18

Articles