연습 - 템플릿을 만들어 구성 요소 재사용

완료됨

피자 회사는 내 주문 페이지에 주문한 피자, 고객이 주문한 시간 등 과거 주문에 대한 자세한 정보를 고객에게 표시하려고 합니다.

템플릿은 Blazing Pizza 앱에서 내 주문 페이지의 표시 및 기능을 개선하는 데 도움이 될 수 있습니다. 이 연습에서는 내 주문 페이지에서 재사용하는 페이지 매김 템플릿 구성 요소를 만듭니다.

페이지 매김 템플릿 구성 요소 만들기

새 Blazor 페이지 매김 템플릿 구성 요소 파일 및 페이지 매김 컨트롤을 만듭니다.

파일을 만들고 태그 추가

  1. Visual Studio Code의 Blazor 앱 프로젝트에서 Components라는 새 폴더를 만든 다음, 이 폴더에 PaginationComponent.razor라는 새 파일을 만듭니다.

  2. 새로 만든 템플릿 구성 요소에 다음 Razor 태그를 추가합니다.

    @typeparam TItem
    
    <div class="container-sm py-4">
        @ItemContent(Items.ElementAt(selectedIndex))
    </div>
    <nav aria-label="Pagination functionality">
        <ul class="pagination pagination-lg justify-content-center">
            <li class="page-item @(previousDisabled ? "disabled" : "")" disabled="@previousDisabled">
                <a class="page-link" @onclick="@(() => SetIndex(0))">
                    <span>⏪</span>
                </a>
            </li>
            <li class="page-item @(previousDisabled ? "disabled" : "")" disabled="@previousDisabled">
                <a class="page-link" @onclick="DecrementIndex"><span>⬅️</span></a>
            </li>
            @foreach ((int index, TItem item) in Items.Select((item, index) => (index, item)))
            {
                var isActive = index == selectedIndex;
                <li class="page-item @(isActive ? "active" :"")">
                    <a class="page-link" @onclick="@(() => SetIndex(index))">
                        @ItemLabel(item)
                    </a>
                </li>
            }
            <li class="page-item @(nextDisabled ? "disabled" : "")" disabled="@nextDisabled">
                <a class="page-link" @onclick="IncrementIndex"><span>➡️</span></a>
            </li>
            <li class="page-item @(nextDisabled ? "disabled" : "")" disabled="@nextDisabled">
                <a class="page-link" @onclick="@(() => SetIndex(Items.Count - 1))">
                    <span>⏩</span>
                </a>
            </li>
        </ul>
    </nav>
    

이 태그는 제네릭 형식 매개 변수 TItem을 허용하고, 선택한 항목을 표시할 컨테이너를 정의하고, <nav> 요소를 사용하여 페이지 매김 컨트롤을 표시합니다.

이 컨트롤은 각 목록 항목이 페이지 번호가 되는 <ul> 요소를 사용합니다. 페이지 번호는 매개 변수로 전달되는 ItemLabel 렌더링 조각에 의해 정의됩니다. ItemLabel 렌더링 조각은 템플릿을 사용하는 구성 요소에서 정의됩니다.

코드 지시문 추가

활성 상태인 항목을 처리하는 @code 지시문을 추가합니다.

@code {
    [Parameter, EditorRequired]
    public required List<TItem> Items { get; set; }

    [Parameter, EditorRequired]
    public required RenderFragment<TItem> ItemContent { get; set; }

    [Parameter, EditorRequired]
    public required Func<TItem, MarkupString> ItemLabel { get; set; }

    int selectedIndex;

    bool previousDisabled => selectedIndex == 0;
    bool nextDisabled => selectedIndex == Items.Count - 1;

    void IncrementIndex() => selectedIndex++;
    void DecrementIndex() => selectedIndex--;
    void SetIndex(int index) => selectedIndex = index;

    protected override void OnInitialized() =>
        selectedIndex = Items.Count - 1;
}

이전 코드 블록은 템플릿을 사용하는 데 필요한 매개 변수를 정의합니다.

  • Items 매개 변수는 표시할 TItem 항목 목록입니다.
  • ItemContent 매개 변수는 선택한 항목의 콘텐츠를 표시하는 방법을 정의하는 렌더링 조각입니다.
  • ItemLabel 매개 변수는 각 항목의 레이블을 표시하는 방법을 정의하는 함수입니다.

selectedIndex 필드는 현재 선택된 항목을 추적합니다. IncrementIndex, DecrementIndexSetIndex 메서드는 선택한 항목 인덱스 변경에 사용됩니다.

OnInitialized 메서드는 처음에 선택한 항목을 목록의 마지막 항목으로 설정합니다.

MyOrders 구성 요소 업데이트

이제 템플릿 구성 요소를 사용하도록 내 주문 페이지를 업데이트합니다.

  1. 탐색기에서 Pages를 확장한 다음, MyOrders.razor를 선택합니다.

  2. 마지막 @inject 지시문 뒤에 @using 지시문을 추가합니다.

    @using BlazingPizza.Components
    

    이 줄을 사용하면 MyOrder 구성 요소가 새로 만든 구성 요소 템플릿을 사용할 수 있습니다.

  3. <div class="main"> 태그 내의 if / else if / else 논리 블록에서 기존 else 분기를 다음 코드로 바꿉니다.

    else
    {
        <PaginationComponent TItem="OrderWithStatus"
            Items="ordersWithStatus.OrderBy(o => o.Order.CreatedTime).ToList()"
            ItemLabel='item => new($"{item.Order.CreatedTime:ddd, MMM. d, yyyy}")'>
            <ItemContent>
                <div class="list-group-item bg-secondary text-white">
                    <div class="col">
                        <h5>@($"{context.Order.CreatedTime:dddd, MMMM d, yyyy hh:mm tt}")</h5>
                        Items:
                        <strong>@context.Order.Pizzas.Count</strong>
                    </div>
                    <div class="col">
                        Status: <strong>@context.StatusText</strong>
                    </div>
                    @if (@context.StatusText != "Delivered")
                    {
                        <div class="col flex-grow-0">
                            <a href="myorders/@context.Order.OrderId" class="btn btn-success">
                                Track &gt;
                            </a>
                        </div>
                    }
                </div>
                <div class="list-group-item">
                    <div class="col">
                        <OrderReview Order="@context.Order" />
                    </div>
                </div>
            </ItemContent>
        </PaginationComponent>
    }
    

이제 코드는 OrderWithStatus의 제네릭 형식, 생성 날짜별로 정렬된 과거 주문 목록 및 각 항목에 대한 레이블을 생성하는 함수를 제공하는 PaginationComponent를 사용합니다. ItemContent 렌더링 조각은 각 항목에 대한 태그를 정의합니다.

업데이트 테스트

  1. Visual Studio Code에서 F5 키를 누르거나 실행>디버깅 시작을 선택합니다.

  2. 앱에서 몇 가지 주문을 제출한 다음, 내 주문을 선택합니다. 주문 목록이 있는 페이지 매김 컨트롤이 표시되고 주문을 선택하여 주문 세부 정보를 로드할 수 있는지 확인합니다.

    새 주문 기록 페이지의 스크린샷.

  3. Shift+F5를 누르거나 Run>디버깅 중지를 선택하여 앱을 중지합니다.