WinJS + универсальные приложения. Изучаем ListView
В предыдущей статье я рассказала о том, как создавать галерею изображений при помощи элемента управления FlipView. Сегодня мы рассмотрим элемент управления ListView, который позволяет не только отображать различные данные в виде списка, но и работать с ними — группировать, перетаскивать и переупорядочивать.
Для начала посмотрим, какие возможности для отображения данных доступны в элементе управления ListView. Если вы не знакомы с библиотекой WinJS, то можете почитать об элементах управления, входящих в библиотеку здесь.
Отображение и связывание данных в элементе управления ListViewДля того, чтобы добавить ListView, добавьте на страницу блок div с атрибутом «data-win-control», и присвойте ему значение WinJS.UI.ListView.
Для работы с ListView вам необходимо:Добавить источники данных Задать шаблон для отображения данных Определить макеты для отображения данных Добавление источника данных Для того, чтобы подготовить данные для добавления в элемент управления ListView, создайте массив: (function () { «use strict»;
var myData = [ { title: «Basic banana», text: «Low-fat frozen yogurt», picture: «images/60banana.png» }, { title: «Banana blast», text: «Ice cream», picture: «images/60banana.png» }, { title: «Brilliant banana», text: «Frozen custard», picture: «images/60banana.png» }, … ];
})(); Каждый из объектов имеет три свойства: заголовок, текст и изображение. В данном примере изображения хранятся локально. Составим из нашего массива объектов список Binding.List: var dataList = new WinJS.Binding.List (myData); Чтобы список был доступен глобально (это требуется для декларативного описания), не забываем создать пространство имен (в данном случае DataExample), которое предоставляет открытый элемент itemList, возвращающий список. Используя функцию WinJS.Namespace.define: var publicMembers = { itemList: dataList }; WinJS.Namespace.define («DataExample», publicMembers); Функция WinJS.Namespace.define принимает два параметра: имя создаваемого пространства имен и объект, содержащий одну или несколько пар свойство-значение. Каждое свойство — это открытое имя элемента, а каждое значение — это базовая переменная, свойство или функция в вашем частном коде, к которым вы хотите открыть доступ.
Для того, чтобы добавить созданный список в элемент управления ListView, необходимо присвоить атрибуту «itemDataSource» значение DataExample.itemList.dataSource.
Не забудьте создать шаблон для отображения данных. О том, как создавать шаблон, вы можете почитать здесь.
На заметку: Для того, чтобы применить шаблон элемента, используйте синтаксис select для задания свойства itemTemplate вашему шаблону элемента объекта ListView.Помимо шаблона для каждого объекта в отдельности, вам необходимо определить один из доступных макетов шаблона для отображения данных элемента управления ListView.
Стандартные макеты для отображения данных элемента управления ListView У элемента ListView есть три стандартных макета для отображения данных — список, сетка и ячейка. Чтобы использовать один из макетов, добавьте для свойства layout значение WinJS.UI.ListLayout, WinJS.UI.GridLayout< или WinJS.UI.CellSpanningLayout. Макеты WinJS.UI.ListLayout WinJS.UI.GridLayout используются для создания списка и сетки элементов, соответственно. Что касается макета WinJS.UI.CellSpanningLayout – он предназначен для того, чтобы создавать сетку с несколькими различными размерами.
Аналогично для Windows:
Макет Список (ListLayout)
Макет Сетка (GridLayout)
Макет Ячейка (Макет CellSpanningLayout)
Стилизация элемента управления ListView Дизайн элемента управления ListView очень легко менять. Для того, чтобы стилизовать элемент управления ListView, можно: Использовать WinJS.Binding.Template для описания шаблона отдельного элемента Описать CSS стили для элементов ListView, к примеру: win-listview задает стиль всего объекта ListView win-viewport задает стиль окна просмотра. Здесь при необходимости отображается полоса прокрутки win-surface задает стиль прокручиваемой области ListView. Если окно просмотра меньше прокручиваемой области, в нем появляются полосы прокрутки С полным списком классов можно ознакомиться на ListView reference page.
Например, можно добавить фоновое изображение и рамку для элемента ListView:
#myListView .win-listview { background-image: url ('…/images/icecream.png'); border: 2 px solid red; }
Отлично! Мы познакомились с элементом управления ListView, рассмотрели создание и добавление данных, а также посмотрели доступные макеты для отображения. Теперь научимся работать с элементами внутри ListView.
Изменение порядка элементов в списке ListView Представьте, что у вас есть список данных, которые вы хотите каким-то образом переупорядочить, поменять строки списка местами. Давайте решим эту задачу.В элементе управления Listview есть свойство itemsReorderable, которое позволяет менять элементы местами. Свойство itemsReorderable принимает два значения: true и false. В случае, если мы хотим разрешить перестановку элементов, присваиваем свойству itemsReorderable значение true.
Обратите внимание: Свойство itemsReorderable недоступно для Windows Phone.
Декларативное задание возможности переупорядочивания элементов
Задачу работы со списком мы решили — теперь мы можем вручную переупорядочить элементы. А что же делать, если мы хотим каким-то образом сгруппировать их? Например, распределить их по группам, в зависимости от первой буквы названия элемента.
Группировка элементов в ListView Рассмотрим пример группировки данных по первой букве названия каждого элемента. Для реализации группировки создайте версию вашего источника данных, которая будет содержать информацию о группировке элементов. Процесс группировки будет следующим: мы сначала отсортируем заголовки групп путем сравнения юникодов начальных букв в строке, а затем приведем заголовки всех групп к одному виду и создадим сами группы. // Сравнение групп по ключам function compareGroups (leftKey, rightKey) { return leftKey.charCodeAt (0) — rightKey.charCodeAt (0); } // Определяем, ключ группы для элемента function getGroupKey (dataItem) { return dataItem.title.toUpperCase ().charAt (0); } // Возвращаем заголовок для группы function getGroupData (dataItem) { return { title: dataItem.title.toUpperCase ().charAt (0) }; } // Создаем новые отсортированные группы var groupedItemsList = itemsList.createGrouped (getGroupKey, getGroupData, compareGroups);
Мы научились распределять элементы по группам. А что же делать, если элементов и групп слишком много и перемещение по списку становится затруднительным? Для этого в библиотеке WinJS предусмотрен элемент управления Semantic Zoom.
Реализуем навигацию в ListView с помощью элемента управления SemanticZoom Элемент управления SemanticZoom позволяет реализовать переключение между двумя различными представлениями элементов. Одно из этих представлений — непосредственно представление содержимого. Второе позволяет реализовать быструю навигацию между содержимым, например, отображать заголовки групп для быстрого доступа к содержимому каждой группы.Для того, чтобы добавить элемент управления SemanticZoom, необходимо создать блок div и присвоить атрибуту data-win-control значение WinJS.UI.SemanticZoom.
Определите три шаблона для объектов ListView: один — для детализированного представления элементов, другой — для заголовков групп в детализированном представлении элементов, а третий — для заголовков групп в общем представлении. Также необходимо добавить 2 элемента управления ListView. Первый будет определять детализированное представление, а второй — общее представление.Перейдем непосредственно к добавлению элемента управления SemanticZoom. Для этого просто добавьте в блок элемента управления SemanticZoom элементы управления ListView для детализированного и общего представления.
Обратите внимание на:
Источники данных (itemDataSource) Шаблоны для отображения данных
Важно! Не забудьте определить собственные стили для общего представления.
С тем, какие возможности можно реализовать внутри одного списка в элементе управления ListView мы познакомились. Следующий этап — работа с несколькими списками, а именно — перемещение элементов из одного списка в другой.
Поддержка перетаскивания в элементе управления ListView Представьте ситуацию, когда у вас есть два списка, и вы хотите переместить элементы из одного списка в другой. Для решения этой задачи вы можете воспользоваться операциями перетаскивания, доступными для элемента управления ListView. Эти операции совместимы с функцией перетаскивания в HTML5. Перетаскивание можно выполнять между двумя элементами управления ListView, между ItemContainer и ListView, а также между любым элементом HTML и ListView. Можно позволить пользователю перетаскивать элементы на определенное место в ListView, а также можно управлять тем, куда вставляются перетаскиваемые элементы. Подробнее об обработке событий перетаскивания в HTML5 можно почитать здесь.Обратите внимание: Перетаскивание элементов недоступно для Windows Phone.Для того, чтобы разрешить перетаскивание элементов из ListView, обработаем его с помощью специальных событий перетаскивания, которые были добавлены в HTML5. Условно всю обработку перетаскивания элемента можно разбить на два шага: Сохранение данных перетаскиваемого элемента в начале операции перетаскивания с помощью метода setData.Извлечение ранее сохраненных данных после того, как перетаскиваемый элемент будет перемещен в принимающий его элемент с помощью метода getData.
Рассмотрим случай, при котором перетаскиваемый элемент добавляется в любое место списка. Обработаем события для перетаскивания элемента.
(function () { «use strict»; var page = WinJS.UI.Pages.define (»/html/drag.html», { ready: function (element, options) { var dragging = false; // Обработка события начала перетаскивания myDragContent.addEventListener («dragstart», function (eventObject) { var dragData = { sourceId: myDragContent.id, data: myItemTitle.innerText, imgSrc: myImg.src }; // Сохранение данных перетаскиваемого элемента eventObject.dataTransfer.setData («Text», JSON.stringify (dragData)); // Разрешаем перетаскивание элемента dragging = true; }); // Обработка события конца перетаскивания myDragContent.addEventListener («dragend», function (eventObject) { dragging = false; }); // Обработка события, при котором перетаскиваемый элемент наведен на тот, который может его принять listView.addEventListener («itemdragenter», function (eventObject) { if (dragging && eventObject.detail.dataTransfer.types.contains («Text»)) { eventObject.preventDefault (); } }); // Обработка события перетаскивания listView.addEventListener («itemdragdrop», function (eventObject) { // Извлечение ранее сохраненных данных после перемещения элемента var dragData = eventObject.detail.dataTransfer && JSON.parse (eventObject.detail.dataTransfer.getData («Text»)); if (dragData && dragData.sourceId === myDragContent.id) { var newItemData = { title: dragData.data, text: («Dragged Item»), picture: dragData.imgSrc }; //Удаляем часть массива и добавляем новые элементы, присваиваем индекс добавленному элементу myData.splice (eventObject.detail.insertAfterIndex + 1, 0, newItemData); } }); } }); })(); Таким образом мы реализовали функцию перетаскивания элемента из одного списка в любое место другого списка. На скриншоте переносимый элемент выделен красным.
Итоги Итак, мы познакомились с элементом управления ListView. Он предоставляет вам возможности работы с элементами списка. Мы рассмотрели различные макеты отображения данных, познакомились со способом реализации изменения порядка элементов в списке, а также с группировкой элементов по первой букве названия каждого элемента. На примере работы с двумя списками, мы реализовали возможность перетаскивания элементов из одного списка в другой. В качестве примера работы ListView с другими элементами управления была рассмотрена возможность реализации навигации при помощи элемента управления Semantic Zoom.Дополнительные ссылки: Краткое руководство: добавление элемента управления ListView (HTML)Краткое руководство: добавление элемента управления Semantic Zoom (HTML)Элементы управления (HTML с JavaScript)Creating a unique ListView layout using cell-spanning in HTMLMVA курс по мобильной разработке для веб-разработчиковСкачать Microsoft Visual Studio можно здесь