Группировка элементов в элементе управления ListView (HTML)

[ Эта статья адресована разработчикам приложений среды выполнения Windows для Windows 8.x и Windows Phone 8.x. В случае разработки приложений для Windows 10 см. раздел последняя документация]

Узнайте, как группировать элементы в ListView. Для отображения сведений о группе, например заголовков и границ группы, элемент управления ListView должен использовать макет сетки. Чтобы группирование работало, для свойства loadingBehavior элемента управления ListView должно быть задано значение "randomaccess" (значение по умолчанию).

Что необходимо знать

Технологии

Необходимые условия

Инструкции

Этап 1: Создание данных

Для группирования необходимы два источника данных: IListDataSource, который содержит элементы, и IListDataSource, который содержит группы. В источнике элементов IListDataSource каждый элемент содержит свойство groupKey, которое связывает его с группой из источника групп IListDataSource, к которой он принадлежит.

  1. Добавьте в проект новый файл JavaScript, который будет содержать ваши данные. Назовите его "data.js".

  2. В только что созданном файле data.js создайте основной источник данных, который будет пополнять данными ваш элемент управления ListView.

    Один из способов создать объект IListDataSource — это создать объект WinJS.Binding.List. Каждый WinJS.Binding.List обладает свойством dataSource, которое возвращает IListDataSource, содержащий ваши данные.

    В данном примере создается объект WinJS.Binding.List из массива объектов в формате JSON (myData):

    
    // Start of data.js
    (function () {
        "use strict";
    
    
    
        var myData = [
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Lavish Lemon Ice", text: "Sorbet", picture: "images/60Lemon.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Marvelous Mint", text: "Gelato", picture: "images/60Mint.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Creamy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Succulent Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Very Vanilla", text: "Ice Cream", picture: "images/60Vanilla.png" },
        { title: "Orangy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Orangy Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Absolutely Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Absolutely Orange", text: "Sorbet", picture: "images/60Orange.png" },
        { title: "Triple Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Triple Strawberry", text: "Sorbet", picture: "images/60Strawberry.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Double Banana Blast", text: "Low-fat frozen yogurt", picture: "images/60Banana.png" },
        { title: "Green Mint", text: "Gelato", picture: "images/60Mint.png" }
        ];
    
        // Create a WinJS.Binding.List from the array. 
        var itemsList = new WinJS.Binding.List(myData);
    

    Примечание  Эти данные относятся к нескольким изображениям. Чтобы получить изображения, скачайте образец группировки ListView и элемента управления SemanticZoom, а затем скопируйте изображения из образца в свой проект. Также можно использовать собственные изображения — только не забывайте обновлять значение свойства picture в ваших данных.

     

    Совет  

    Не ограничивайте себя только объектом WinJS.Binding.List: можно использовать пользовательский объект VirtualizedDataSource. (StorageDataSource не поддерживает группирование.) Подробнее о создании пользовательского источника данных см. в разделе Создание пользовательского источника данных.

     

  3. Создание версии источника данных, которая содержит информацию о группировании. Если вы используете WinJS.Binding.List, вы можете осуществить вызов его метода createGrouped, чтобы создать сгруппированную версию объекта List.

    Метод createGrouped принимает три параметра:

    • getGroupKey: функция, которая при наличии элемента в списке возвращает ключ группы, к которой принадлежит элемент.
    • getGroupData: функция, которая при наличии элемента в списке возвращает объект данных, представляющий группу, к которой принадлежит элемент.
    • compareGroups: функция, которая используется для сортировки групп так, что группа А находится перед группой Б. Эта функция сравнивает две группы ключей и возвращает: значение меньше нуля, если первая группа меньше второй; значение, равное нулю, если группы одинаковые; значение больше нуля, если первая группа больше второй.

    Метод createGrouped возвращает объект WinJS.Binding.List, содержащий две проекции данных из исходного несгруппированного списка. Проекции динамичны, поэтому если вы изменяете список, изменяйте его исходный вариант.

    В этом примере используется метод List.createGrouped для создания сгруппированной версии элемента управления List. Для определения групп он использует первую букву названия каждого элемента.

        // Sorts the groups
        function compareGroups(leftKey, rightKey) {
            return leftKey.charCodeAt(0) - rightKey.charCodeAt(0);
        }
    
        // Returns the group key that an item belongs to
        function getGroupKey(dataItem) {
            return dataItem.title.toUpperCase().charAt(0);
        }
    
        // Returns the title for a group
        function getGroupData(dataItem) {
            return {
                title: dataItem.title.toUpperCase().charAt(0)
            };
        }
    
        // Create the groups for the ListView from the item data and the grouping functions
        var groupedItemsList = itemsList.createGrouped(getGroupKey, getGroupData, compareGroups);
    
  4. Сделайте ваши данные доступными в глобальном контексте. Таким образом, когда вы создадите объект ListView, вы сможете получить доступ к данным декларативно (мы покажем, как это сделать, на шаге 2.3).

    В этом примере для обеспечения открытого доступа к сгруппированному списку используется WinJS.Namespace.define.

        WinJS.Namespace.define("myData",
            {
                groupedItemsList: groupedItemsList
            }); 
    
    
    })(); // End of data.js
    

Этап 2: Создание элемента управления ListView, использующего макет сетки

Далее создайте элемент управления ListView и свяжите его с вашими данными.

  1. В разделе head вашей HTML-страницы, которая будет содержать элемент управления ListView, добавьте ссылку на файл данных, созданный на предыдущем шаге.

    
    
        <!-- Your data file. -->
        <script src="/js/data.js"></script>
    
  2. В разделе body вашего HTML-файла создайте элемент управления ListView. Задайте для свойства layout значение GridLayout.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{layout: {type: WinJS.UI.GridLayout}}"
    ></div>
    
  3. Установите для элементов управления ListView в свойстве itemDataSource источник данных сгруппированных элементов.

    В шаге 1 создан член пространства имен, содержащий сгруппированные элементы, которые необходимо отобразить: myData.groupedItemsList. Вызов данного поля возвращает WinJS.Binding.List. Для получения IListDataSource, что может использовать ListView, вызовите его свойство dataSource: myData.groupedItemsList.dataSource.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
            layout: {type: WinJS.UI.GridLayout}}"
    ></div>
    
  4. Затем в элементе управления ListView укажите для свойства groupDataSource источник данных, который содержит данные группы. Используйте в объекте List свойство groups, чтобы получить другой объект List, который содержит сведения о группе. Для получения интерфейса IListDataSource вы вызываете myData.groupedItemsList.groups.dataSource.

    
    <div id="groupedListView"
        data-win-control="WinJS.UI.ListView" 
        data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
            groupDataSource: myData.groupedItemsList.groups.dataSource,
            layout: {type: WinJS.UI.GridLayout}}">
    </div>
    

Запустите приложение. Так как вы не задали шаблоны элементов, данные не будут отформатированы.

Элемент управления ListView, отображающий необработанные данные группы.

Этап 3: Создание шаблона элемента и шаблона заголовка группы

В вашей HTML-странице до определения ListView создайте объект WinJS.UI.Template с именем "mediumListIconTextTemplate" и установите в свойстве itemTemplate элемента управления ListView имя этого шаблона.


<div id="mediumListIconTextTemplate" 
    data-win-control="WinJS.Binding.Template" 
    style="display: none">
    <div class="mediumListIconTextItem">
        <img class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
        <div class="mediumListIconTextItem-Detail">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>
</div>

<div id="groupedListView"
    data-win-control="WinJS.UI.ListView" 
    data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
        itemTemplate: select('#mediumListIconTextTemplate'),
        groupDataSource: myData.groupedItemsList.groups.dataSource,
        layout: {type: WinJS.UI.GridLayout}}">
</div>

(Примечание. Шаблоном устанавливается несколько стилей. Мы определим их позже.)

Запустите приложение. Элементы отформатированы, в отличие от заголовков группы.

Элемент управления ListView, отображающий необработанные данные группы.

Этап 4: Создание шаблона заголовка группы

Определите WinJS.UI.Template для заголовка группы и присвойте ему идентификатор шаблона "headerTemplate". Установите для элемента управления ListView в свойстве groupHeaderTemplate этот шаблон.


<div id="headerTemplate" data-win-control="WinJS.Binding.Template" 
    style="display: none">
    <div class="simpleHeaderItem">
        <h1 data-win-bind="innerText: title"></h1>
    </div>
</div>

<div id="mediumListIconTextTemplate" 
    data-win-control="WinJS.Binding.Template" 
    style="display: none">
    <div class="mediumListIconTextItem">
        <img class="mediumListIconTextItem-Image" data-win-bind="src: picture" />
        <div class="mediumListIconTextItem-Detail">
            <h4 data-win-bind="innerText: title"></h4>
            <h6 data-win-bind="innerText: text"></h6>
        </div>
    </div>
</div>

<div id="groupedListView"
    data-win-control="WinJS.UI.ListView" 
    data-win-options="{itemDataSource: myData.groupedItemsList.dataSource, 
        itemTemplate: select('#mediumListIconTextTemplate'),
        groupDataSource: myData.groupedItemsList.groups.dataSource,
        groupHeaderTemplate: select('#headerTemplate'),
        layout: {type: WinJS.UI.GridLayout}}">
</div>

Запустите приложение. В данный момент элементы и заголовки группы отформатированы.

Элемент управления ListView, отображающий сгруппированные данные.

Этап 5: Задание стиля отображения для ваших шаблонов

Если требуется определить более подробно внешний вид элементов и заголовков, вы можете задать собственные стили CSS в таблице стилей. В следующем примере CSS задает стиль отображения для элементов, заголовков и самого элемента управления ListView.


/* CSS for the ListView */
#groupedListView
{
    width: 600px;
    height: 300px;
    border: solid 2px rgba(0, 0, 0, 0.13);
}

/* Template for headers */
.simpleHeaderItem
{
    width: 50px;
    height: 50px;
    padding: 8px;
}   

/* Template for items */  
.mediumListIconTextItem
{
    width: 282px;
    height: 70px;
    padding: 5px;
    overflow: hidden;
    display: -ms-grid;
}

    .mediumListIconTextItem img.mediumListIconTextItem-Image 
    {
        width: 60px;
        height: 60px;
        margin: 5px;
        -ms-grid-column: 1;
    }

    .mediumListIconTextItem .mediumListIconTextItem-Detail
    {
        margin: 5px;
        -ms-grid-column: 2;
    }

После запуска приложения элементы будут разделены на группы:

Сгруппированные элементы в ListView

Также вы можете задать стиль для ваших групп и элементов с помощью CSS-классов win-groupheader и win-container. Подробности см. в статье Стили элементов управления ListView и их элементов.

Примечания

Сортировка и фильтрация элементов и групп

Объект WinJS.Binding.List может сортировать и фильтровать элементы и группы. Дополнительные сведения см. в описании методов createSorted и createFiltered.

Создание увеличенного вида ваших групп

Теперь, когда вы знакомы с созданием сгруппированных элементов управления ListView, для вас не составит труда научиться использовать элемент управления SemanticZoom для создания увеличенного вида ваших групп.

Общее и детализированное представления элемента управления контекстного масштабирования

Инструкции по использованию SemanticZoom см. в разделе Краткое руководству. Добавление элементов управления SemanticZoom.

Сгруппированные элементы управления ListView, содержащие интерактивные заголовки

Если ваши сгруппированные элементы управления ListView содержат интерактивные заголовки, мы рекомендуем поддерживать сочетание клавиш CTRL+ALT+G и использовать его для перемещения пользователя в просматриваемую группу. Результат должен быть таким же, как и при щелчке или касании заголовка группы.

Удаление групп и прокрутка

При удалении группы элемент управления ListView может прокрутиться в неожиданное положение, поэтому вызовите метод ensureVisible для прокрутки в положение, осмысленное в вашем приложении.

Полный пример

Полный пример создания сгруппированного элемента управления ListView см. в разделе Элемент управления SemanticZoom и группирование элемента управления ListView.

Связанные разделы

Элемент управления SemanticZoom и группирование элемента управления ListView

Краткое руководство: добавление элементов управления SemanticZoom