演習 - テンプレートを作成することによってコンポーネントを再利用する
ピザ会社は、[ 注文 ] ページに、注文したピザや注文時刻など、過去の注文に関する詳細を顧客に表示することを望んでいます。
テンプレートを使用すると、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 レンダリング フラグメントでは、各項目のマークアップが定義されています。