Введение
Вышла уже четвертая альфа 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. Объяснения, как оно работает, чуть ниже.
- // do all stuff on document ready
- $(document).ready(function(){
- $("#load-data").click(function(){
- // show loading indicator
- $.mobile.pageLoading();
- $.getJSON("api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
- {
- tags: "cat",
- tagmode: "any",
- format: "json"
- },
- function(data) {
- // render data into templates and append to list
- $("#dataTemplate").tmpl(data.items).appendTo("#data-listholder");
- // refresh list view
- $("#data-listholder").listview("refresh");
- // hide loading indicator
- $.mobile.pageLoading(true);
- });
- });
- });
Строки 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 в соответствующем разделе. Вопросы можно и нужно задавать, постараюсь ответить на все.