Exercice - Réutiliser des composants en créant un modèle

Effectué

La société de vente de pizzas veut que la page My Orders (Mes commandes) montre aux clients plus de détails sur leurs commandes passées, comme les pizzas qui figuraient dans la commande et l’heure à laquelle le client a passé la commande.

Un modèle peut vous aider à améliorer l’affichage et les fonctionnalités de la page My Orders dans l’application Blazing Pizza. Dans cet exercice, vous créez un composant modèle de pagination que vous réutilisez sur la page My Orders.

Créer le composant de modèle de pagination

Créez un fichier de composant modèle de pagination Blazor et des contrôles de pagination.

Créer le fichier et ajouter le balisage

  1. Dans votre projet d’application Blazor dans Visual Studio Code, créez un dossier nommé Components, puis créez un fichier dans le dossier nommé PaginationComponent.razor.

  2. Ajoutez le code de balisage Razor suivant au composant modèle nouvellement créé :

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

Le balisage accepte un paramètre TItem de type générique, définit un conteneur pour afficher l’élément sélectionné et utilise un élément <nav> pour afficher les contrôles de pagination.

Les contrôles utilisent un élément <ul>, chaque élément de la liste étant un numéro de page. Le numéro de page est défini par le fragment de rendu de ItemLabel, qui est passé en tant que paramètre. Le fragment de rendu ItemLabel est défini dans le composant qui utilise le modèle.

Ajouter la directive code

Ajoutez la directive @code pour gérer quel élément est actif.

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

Le bloc de code précédent définit les paramètres qui sont nécessaires pour utiliser le modèle.

  • Le paramètre Items est une liste d’éléments TItem à afficher.
  • Le paramètre ItemContent est un fragment de rendu qui définit comment afficher le contenu d’un élément sélectionné.
  • Le paramètre ItemLabel est une fonction qui définit comment afficher l’étiquette pour chaque élément.

Le champ selectedIndex est utilisé pour suivre quel élément est actuellement sélectionné. Les méthodes IncrementIndex, DecrementIndex et SetIndex sont utilisées pour modifier l’index d’élément sélectionné.

La méthode OnInitialized définit l’élément sélectionné initial sur le dernier élément de la liste.

Mettre à jour le composant MyOrders

À présent, mettez à jour la page My Orders pour utiliser le composant modèle.

  1. Dans l’Explorateur, développez Pages, puis sélectionnez MyOrders.razor.

  2. Après la dernière directive @inject, ajoutez la directive @using :

    @using BlazingPizza.Components
    

    Cette ligne permet au composant MyOrder d’utiliser le composant modèle nouvellement créé.

  3. Dans le balisage <div class="main">, dans le bloc logique if / else if / else, remplacez la branche else existante par le code suivant :

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

Le code s’appuie désormais sur PaginationComponent, fournissant le type générique de OrderWithStatus, une liste des commandes passées triées par date de création et une fonction pour générer l’étiquette pour chaque élément. Le fragment de rendu ItemContent définit le balisage pour chaque élément.

Test des modifications

  1. Dans Visual Studio Code, appuyez sur F5 ou sélectionnez Exécuter>Démarrer le débogage.

  2. Dans l’application, passez deux commandes, puis sélectionnez My Orders. Vérifiez que vous voyez un contrôle de pagination avec une liste de vos commandes et que vous pouvez sélectionner une commande pour en charger les détails.

    Capture d’écran de la nouvelle page d’historique des commandes.

  3. Appuyez sur Maj+F5 ou sélectionnez Exécuter>Arrêter le débogage pour arrêter l’application.