Ejercicio: Reutilización de componentes mediante la creación de plantillas

Completado

La empresa de pizzas quiere que la página My Orders muestre a los clientes más detalles sobre sus pedidos anteriores, como qué pizzas se incluyeron en el pedido y en qué momento el cliente hizo el pedido.

Una plantilla puede ayudarle a mejorar la visualización y la funcionalidad de la página My Orders en la aplicación Blazing Pizza. En este ejercicio, creará un componente de plantilla de paginación que reutilizará en la página My Orders.

Creación del componente de plantilla de paginación

Cree un nuevo archivo de componente de plantilla de paginación de Blazor y controles de paginación.

Creación del archivo y agregación del marcado

  1. En el proyecto de la aplicación de Blazor en Visual Studio Code, cree una carpeta Components y, luego, cree un nuevo archivo en la carpeta PaginationComponent.razor.

  2. Agregue el siguiente marcado de Razor al componente de plantilla recién creado:

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

El marcado acepta un parámetro TItem de tipo genérico, define un contenedor para mostrar el elemento seleccionado y usa un elemento <nav> para mostrar los controles de paginación.

Los controles usan un elemento <ul> en el que cada elemento de la lista es un número de página. El número de página se define mediante el fragmento de representación ItemLabel, que se pasa como parámetro. El fragmento de representación ItemLabel se define en el componente que usa la plantilla.

Adición de la directiva de código

Agregue la directiva @code para controlar qué elemento está activo.

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

El bloque de código anterior define los parámetros necesarios para usar la plantilla.

  • El parámetro Items es una lista de TItem elementos que se van a mostrar.
  • El parámetro ItemContent es un fragmento de representación que define cómo mostrar el contenido de un elemento seleccionado.
  • El parámetro ItemLabel es una función que define cómo mostrar la etiqueta para cada elemento.

El campo selectedIndex realiza un seguimiento de qué elemento está seleccionado actualmente. Los métodos IncrementIndex, DecrementIndex y SetIndex se usan para cambiar el índice de elemento seleccionado.

El método OnInitialized se usa para establecer el elemento seleccionado inicial en el último elemento de la lista.

Actualización del componente MyOrders

Ahora, actualice la página My Orders para usar el componente de plantilla.

  1. En el Explorador, expanda Páginas y seleccione MyOrders.razor.

  2. Después de la última directiva @inject, agregue la directiva @using:

    @using BlazingPizza.Components
    

    Esta línea permite al componente MyOrder usar la plantilla de componente recién creada.

  3. Dentro del marcado <div class="main">, en el bloque lógico if / else if / else, reemplace la rama else existente por el código siguiente:

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

El código ahora se basa en PaginationComponent, proporcionando el tipo genérico de OrderWithStatus, una lista de pedidos anteriores ordenados por su fecha de creación y una función para generar la etiqueta para cada elemento. El fragmento de representación ItemContent define el marcado de cada elemento.

Prueba de las actualizaciones

  1. En Visual Studio Code, presione F5 o seleccione Ejecutar>Iniciar depuración.

  2. En la aplicación, realice un par de pedidos y, luego, seleccione My Orders. Compruebe que ve un control de paginación con una lista de los pedidos y que puede seleccionar un pedido para cargar sus detalles.

    Captura de pantalla de la nueva página del historial de pedidos.

  3. Presione Mayús+F5 o seleccione Ejecutar>Detener depuración para detener la aplicación.