ListView에서 항목을 그룹화하는 방법(HTML)

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

ListView에서 항목을 그룹화하는 방법을 알아봅니다. 그룹 헤더, 그룹 경계 등 그룹 정보를 표시하려면 ListView가 그리드 레이아웃을 사용해야 합니다. 그룹화가 작동하려면 ListView 컨트롤의 loadingBehavior 속성을 "randomaccess"(기본값)로 설정해야 합니다.

알아야 할 사항

기술

사전 요구 사항

지침

단계 1: 데이터 만들기

그룹화에는 두 개의 데이터 원본(항목이 포함된 IListDataSource 및 그룹이 포함된 IListDataSource)이 필요합니다. 항목 IListDataSource의 각 항목에는 IListDataSource 그룹에서 항목이 속하는 그룹에 항목을 연결하는 groupKey 속성이 있습니다.

  1. 데이터를 포함할 새 JavaScript 파일을 프로젝트에 추가합니다. 이름을 "data.js"로 지정합니다.

  2. 방금 만든 data.js 파일에서 ListView 컨트롤에 데이터를 제공할 기본 데이터 원본을 만듭니다.

    IListDataSource를 만드는 방법 중 하나는 WinJS.Binding.List를 만드는 것입니다. 각 WinJS.Binding.List에는 데이터가 포함된 IListDataSource를 반환하는 dataSource 속성이 있습니다.

    다음 예제에서는 JSON 개체 배열(myData)에서 WinJS.Binding.List를 만듭니다.

    
    // 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 메서드는 다음 3개의 매개 변수를 사용합니다.

    • getGroupKey: 목록에 항목이 있을 경우 항목이 속하는 그룹 키를 반환하는 함수입니다.
    • getGroupData: 목록에 항목이 있을 경우 항목이 속하는 그룹을 나타내는 데이터 개체를 반환하는 함수입니다.
    • compareGroups: 그룹 A가 그룹 B 앞에 오도록 그룹을 정렬하는 데 사용되는 함수입니다. 이 함수는 두 그룹 키를 입력으로 사용하고 두 그룹을 비교한 다음 첫 번째 그룹이 두 번째 그룹보다 작으면 0보다 작은 값을 반환하고, 두 그룹이 같으면 0을 반환하고, 첫 번째 그룹이 두 번째 그룹보다 크면 양수 값을 반환합니다.

    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. ListView가 포함될 HTML 페이지의 head 섹션에 앞 단계에서 만든 데이터 파일에 대한 참조를 추가합니다.

    
    
        <!-- Your data file. -->
        <script src="/js/data.js"></script>
    
  2. HTML 파일의 body에서 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가 반환됩니다. ListView가 사용할 수 있는 IListDataSource를 가져오려면 해당 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를 정의하기 전에 이름이 "mediumListIconTextTemplate"인 WinJS.UI.Template을 만들고 ListView 컨트롤의 itemTemplate 속성을 이 템플릿의 이름으로 설정합니다.


<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를 정의하고 ID를 "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

win-groupheaderwin-container CSS 클래스를 사용하여 그룹 및 항목 스타일을 지정할 수도 있습니다. 자세한 내용은 ListView 및 해당 항목 스타일 지정을 참조하세요.

설명

항목 및 그룹 정렬 및 필터링

WinJS.Binding.List는 항목 및 그룹을 정렬하고 필터링할 수 있습니다. 자세한 내용은 createSortedcreateFiltered 메서드를 참조하세요.

그룹의 축소 보기를 만드는 방법

그룹화된 ListView를 만드는 방법을 배웠으므로 SemanticZoom 컨트롤을 사용하여 축소된 그룹 보기를 만들기 위해 알아야 할 사항은 그리 많지 않습니다.

SemanticZoom 컨트롤의 확대/축소 보기

SemanticZoom을 사용하는 방법에 대한 자세한 내용은 빠른 시작: SemanticZoom 컨트롤 추가를 참조하세요.

대화형 머리글을 포함한 그룹화된 ListView 컨트롤

사용자의 그룹화된 ListView 컨트롤은 대화형 머리글을 포함합니다. Ctrl+Alt+G 키보드 바로가기를 권장하며 이를 사용하여 현재 검색하는 그룹에 사용자를 이동할 수 있습니다. 그룹 머리말 자체를 클릭하거나 탭하여 동일한 동작을 제공해야 합니다.

그룹 삭제 및 스크롤

그룹이 삭제되면 ListView는 예기치 못한 위치로 스크롤될 수 있습니다. 그래서 ensureVisible 방법으로 앱에 적절한 위치로 스크롤합니다.

전체 예제

그룹화된 ListView를 만드는 방법을 보여 주는 전체 샘플은 ListView 그룹화 및 SemanticZoom 샘플을 참조하세요.

관련 항목

ListView 그룹화 및 SemanticZoom

빠른 시작: SemanticZoom 컨트롤 추가