演習 - テンプレートを作成することによってコンポーネントを再利用する
このピザ会社は、[自分の注文] ページに、過去の注文に関する詳細 (注文したピザや、顧客が注文した時刻など) を顧客に表示したいと考えています。
テンプレートは、Blazing Pizza アプリの [自分の注文] ページの表示と機能を改善するのに役立ちます。 この演習では、[自分の注文] ページで再利用する改ページ位置の自動修正テンプレート コンポーネントを作成します。
改ページ位置の自動修正テンプレート コンポーネントを作成する
新しい Blazor 改ページ位置の自動修正テンプレート コンポーネント ファイルと改ページ位置の自動修正コントロールを作成します。
ファイルを作成してマークアップを追加する
Visual Studio Code の Blazor アプリ プロジェクトで、Components という名前の新しいフォルダーを作成してから、そのフォルダーに PaginationComponent.razor という名前の新しいファイルを作成します。
新しく作成したテンプレート コンポーネントに、次の 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
、DecrementIndex
、SetIndex
の各メソッドは、選択した項目のインデックスを変更するために使用されます。
OnInitialized
メソッドは、最初に選択された項目をリストの最後の項目に設定します。
MyOrders コンポーネントを更新する
次に、テンプレート コンポーネントを使うように [自分の注文] ページを更新します。
エクスプローラーで、[ページ] を展開してから、MyOrders.razor を選びます。
最後の
@inject
ディレクティブの後に、@using
ディレクティブを追加します。@using BlazingPizza.Components
この行により、
MyOrder
コンポーネントは新しく作成されたコンポーネント テンプレートを使用できます。<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 > </a> </div> } </div> <div class="list-group-item"> <div class="col"> <OrderReview Order="@context.Order" /> </div> </div> </ItemContent> </PaginationComponent> }
これでコードが PaginationComponent
に依存するようになり、OrderWithStatus
のジェネリック型、作成日順に並べ替えられた過去の注文の一覧、各項目のラベルを生成する関数が提供されます。 ItemContent
レンダリング フラグメントでは、各項目のマークアップが定義されています。
更新をテストする
Visual Studio Code で、F5 キーを押すか、[実行]>[デバッグの開始] を選びます。
アプリで、いくつかの注文を行って、[自分の注文] を選びます。 注文の一覧を含む改ページ位置の自動修正コントロールが表示され、注文を選んで注文の詳細を読み込むことができることを確認します。
Shift+F5 キーを押すか、[実行]>[デバッグの停止] を選んで、アプリを停止します。