Übung: Wiederverwenden von Komponenten durch das Erstellen einer Vorlage

Abgeschlossen

Der Pizza-Laden möchte auf der Seite Meine Bestellungen den Kund*innen weitere Details zu ihren vergangenen Bestellungen bereitstellen, z. B. welche Pizzas in der Bestellung enthalten waren und wann die Kund*innen die Bestellung getätigt haben.

Eine Vorlage kann helfen, die Anzeige und Funktionalität der Seite Meine Bestellungen der Blazing Pizza-App zu verbessern. In dieser Übung erstellen Sie eine Paginierungsvorlagen-Komponente, die Sie auf der Seite Meine Bestellungen wiederverwenden.

Erstellen der Paginierungsvorlagenkomponente

Erstellen Sie eine neue Komponentendatei für Blazor-Paginierungsvorlagen und Paginierungssteuerelemente.

Erstellen der Datei und Hinzufügen des Markup

  1. Erstellen Sie in Ihrem Projekt für die Blazor-App in Visual Studio Code einen neuen Ordner namens Components und dann eine neue Datei im Ordner PaginationComponent.razor.

  2. Fügen Sie der neu erstellten Vorlagenkomponente das folgende Razor-Markup hinzu:

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

Das Markup akzeptiert einen generischen Typparameter TItem, definiert einen Container zum Anzeigen des ausgewählten Elements und verwendet ein <nav>-Element zum Anzeigen der Paginierungssteuerelemente.

Die Steuerelemente verwenden ein <ul>-Element, wobei jedes Listenelement einer Seitenzahl entspricht. Die Seitenzahl wird durch das Renderfragment ItemLabel definiert, das als Parameter übergeben wird. Das ItemLabel-Renderfragment wird in der Komponente definiert, die die Vorlage verwendet.

Hinzufügen der Codeanweisung

Fügen Sie die @code-Anweisung hinzu, um zu steuern, welches Element aktiv ist.

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

Der davor stehende Codeblock definiert die für das Verwenden der Vorlage erforderlichen Parameter.

  • Der Parameter Items ist eine Liste der anzuzeigenden TItem-Elemente.
  • Der Parameter ItemContent ist ein Renderfragment, das definiert, wie der Inhalt eines ausgewählten Elements angezeigt wird.
  • Der Parameter ItemLabel ist eine Funktion, die definiert, wie die Bezeichnung für die einzelnen Elemente angezeigt wird.

Mit dem Feld selectedIndex wird nachverfolgt, welches Element derzeit ausgewählt ist. Die Methoden IncrementIndex, DecrementIndex und SetIndex werden verwendet, um den ausgewählten Elementindex zu ändern.

Mithilfe der Methode OnInitialized wird das anfänglich ausgewählte Element auf das letzte Element in der Liste festgelegt.

Aktualisieren der MyOrders-Komponente

Aktualisieren Sie nun die Seite Meine Bestellungen, um die Vorlagenkomponente zu verwenden.

  1. Erweitern Sie im ExplorerPages, und wählen Sie dann MyOrders.razor aus.

  2. Fügen Sie unter der letzten @inject-Anweisung die Anweisung @using hinzu:

    @using BlazingPizza.Components
    

    Mit dieser Zeile wird die Komponente MyOrder zum Verwenden der neu erstellten Komponentenvorlage aktiviert.

  3. Innerhalb des <div class="main">-Markups befindet sich der logische Block if / else if / else. Ersetzen Sie den vorhandenen else-Branch durch den folgenden Code:

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

Der Code basiert nun auf der PaginationComponent, die den generischen Typ von OrderWithStatus, eine Liste der vergangenen Bestellungen (nach Erstellungsdatum sortiert), und eine Funktion zum Generieren der Bezeichnung für die einzelnen Elemente bereitstellt. Das Renderfragment ItemContent definiert das Markup für die einzelnen Elemente.

Testen Ihrer Aktualisierungen

  1. Drücken Sie in Visual Studio Code F5, oder wählen Sie im Menü Ausführen>Debugging starten aus.

  2. Tätigen Sie in der App einige Bestellungen, und wählen Sie dann Meine Bestellungen aus. Vergewissern Sie sich, dass ein Paginierungssteuerelement mit einer Liste Ihrer Bestellungen angezeigt wird, und Sie eine Bestellung auswählen können, um die Auftragsdetails zu laden.

    Screenshot: Neue Seite zum Bestellverlauf

  3. Drücken Sie UMSCHALT+F5, oder wählen Sie Ausführen>Debugging beenden aus, um die App zu beenden.