Exercício – Reutilizar componentes criando um modelo

Concluído

A pizzaria quer que a página Meus Pedidos mostre aos clientes mais detalhes sobre os pedidos anteriores, como quais pizzas estavam no pedido e a que horas o cliente fez o pedido.

Um modelo pode ajudar a aprimorar a exibição e a funcionalidade da página Meus Pedidos no aplicativo Blazing Pizza. Neste exercício, você cria um componente de modelo de paginação que é reutilizado na página Meus Pedidos.

Criar o componente de modelo de paginação

Crie um arquivo de componente de modelo de paginação e controles de paginação Blazor.

Criar o arquivo e adicionar a marcação

  1. No projeto de aplicativo Blazor no Visual Studio Code, crie uma pasta chamada Componentes e um arquivo na pasta chamado PaginationComponent.razor.

  2. Adicione a seguinte marcação Razor ao componente de modelo recém-criado:

    @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>
    

A marcação aceita um parâmetro de tipo genérico TItem, define um contêiner para exibir o item selecionado e usa um elemento <nav> para exibir os controles de paginação.

Os controles usam um elemento <ul> e cada item de lista é um número de página. O número da página é definido pelo fragmento de renderização ItemLabel, que é passado como um parâmetro. O fragmento de renderização ItemLabel é definido no componente que usa o modelo.

Adicionar a diretiva de código

Adicione a diretiva @code para identificar qual item está ativo.

@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;
}

O bloco de código anterior define os parâmetros necessários para usar o modelo.

  • O parâmetro Items é uma lista de itens TItem a serem exibidos.
  • O parâmetro ItemContent é um fragmento de renderização que define como exibir o conteúdo de um item selecionado.
  • O parâmetro ItemLabel é uma função que define como exibir o rótulo de cada item.

O campo selectedIndex acompanha qual item está selecionado no momento. Os métodos IncrementIndex, DecrementIndex e SetIndex são usados para alterar o índice de item selecionado.

O método OnInitialized define o item selecionado inicial como o último item na lista.

Atualizar o componente MyOrders

Agora, atualize a página Meus Pedidos para usar o componente de modelo.

  1. No Explorer, expanda Páginas e selecine MyOrders.razor.

  2. Após a última diretiva @inject, adicione a diretiva @using:

    @using BlazingPizza.Components
    

    Essa linha permite que o componente MyOrder use o modelo de componente recém-criado.

  3. Dentro da marcação <div class="main">, no bloco lógico if / else if / else, substitua o branch else existente pelo seguinte código:

    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>
    }
    

O código agora depende do PaginationComponent, fornecendo o tipo genérico de OrderWithStatus, uma lista de pedidos anteriores classificados pela data de criação e uma função para gerar o rótulo para cada item. O fragmento de renderização ItemContent define a marcação de cada item.

Testar suas atualizações

  1. No Visual Studio Code, pressione F5 ou selecione Executar>Iniciar Depuração.

  2. No aplicativo, faça alguns pedidos e selecione Meus Pedidos. Verifique se você vê um controle de paginação com uma lista dos pedidos e se consegue selecionar um pedido para carregar seus detalhes.

    Captura de tela da página novo histórico de pedido.

  3. Pressione Shift+F5 ou selecione Executar>Parar Depuração para interromper o aplicativo.