Blazor コンポーネントからデータにアクセスする
- 7 分
魅力のある Web サイトでは、常に変更される可能性のある動的コンテンツを表示する必要があります。 データベースや Web サービスなどの動的ソースからデータを取得することは、Web 開発における基本的な手法です。
あなたは宅配ピザの会社で、更新されたお客様向けの Web サイトに取り組んでいるとします。 さまざまな Web ページを Blazor コンポーネントとしてレイアウトし、設計しました。 ここで、データベースから取得する、ピザ、トッピング、および注文に関する情報をそれらのページに設定したいと考えます。
このユニットでは、ユーザーに表示するために、データにアクセスして、HTML マークアップ内にそれをレンダリングする方法について説明します。
登録済みデータ サービスを作成する
ユーザーに変化する情報を表示する動的 Web サイトを作成する場合、どこかからデータを取得するコードを記述する必要があります。 たとえば、会社で販売しているすべてのピザを格納するデータベースがあるとします。 ピザは常に変更されているため、Web サイトの HTML にそれらをハードコーディングするのは不適切な考えです。 代わりに、C# コードと Blazor を使用して、ユーザーが好きなものを選択できるように、データベースのクエリを実行し、詳細を HTML として書式設定します。
Blazor Server アプリでは、データソースを表し、そこからデータを取得する登録済みサービスを作成できます。
Note
Blazor アプリで使用できるデータのソースには、リレーショナル データベース、NoSQL データベース、Web サービス、各種 Azure サービス、およびその他の多くのシステムが含まれます。 Entity Framework、HTTP クライアント、ODBC などの .NET テクノロジを使用して、それらのソースのクエリを実行できます。 これらの手法は、このモジュールの範囲を超えています。 ここでは、これらのいずれかのソースとテクノロジから取得したデータを書式設定して、使用する方法について説明します。
登録済みサービスの作成では、最初にそのプロパティを定義するクラスを記述します。 ピザを表すために記述できる例を次に示します。
namespace BlazingPizza.Data;
public class Pizza
{
public int PizzaId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public bool Vegetarian { get; set; }
public bool Vegan { get; set; }
}
クラスでは、ピザのプロパティとデータ型を定義します。 これらのプロパティがデータ ソースのピザ スキーマと一致していることを確認する必要があります。 このクラスを、プロジェクトの Data フォルダーに作成し、Data という名前のメンバー名前空間を使用することは適切です。 必要に応じて、他のフォルダーや名前空間にすることもできます。
次に、サービスを定義します。
namespace BlazingPizza.Data;
public class PizzaService
{
public Task<Pizza[]> GetPizzasAsync()
{
// Call your data access technology here
}
}
サービスでは非同期呼び出しを使用してデータにアクセスし、Pizza
オブジェクトのコレクションを返すことに注意してください。 データ ソースは、Blazor コードが実行されているサーバーから離れた場所にある可能性があります。 その場合は、非同期呼び出しを使用します。 そのとき、データ ソースの応答が遅い場合は、応答を待っている間に他のコードの実行を継続できます。
Program.cs ファイルの Add Services to the container
セクションに次の行を追加することで、サービスを登録します。
...
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// Register the pizzas service
builder.Services.AddSingleton<PizzaService>();
...
サービスを使用してデータを取得する
次に、Blazor コンポーネントで呼び出し、データを取得することによって、定義したサービスを使用します。 たとえば、次のコンポーネント コードがあり、その中にピザを表示するとします。
@page "/pizzas"
<h1>Choose your pizza</h1>
<p>We have all these delicious recipes:</p>
サービスを挿入する
コンポーネントからサービスを呼び出す前に、依存関係の挿入を使用してサービスを追加する必要があります。 @page
ディレクティブの後に次のコードを追加してサービスを挿入します。
@using BlazingPizza.Data
@inject PizzaService PizzaSvc
通常、コンポーネントとサービスは異なる名前空間メンバーに属するため、@using
ディレクティブを含める必要があります。 このディレクティブは、C# コード ファイルの先頭にある using
ステートメントと同じように機能します。 @inject
ディレクティブは、現在のコンポーネントにサービスを追加し、そのインスタンスを開始します。 ディレクティブで、サービス クラスの名前を指定します。 その後に、このコンポーネントのサービスのインスタンスに使用する名前を続けます。
OnInitializedAsync メソッドをオーバーライドする
サービスを呼び出してデータを取得するのに適切な場所は、OnInitializedAsync
メソッド内です。 このイベントは、コンポーネントの初期化が完了し、初期パラメーターを受け取っていますが、ページがレンダリングされてユーザーに表示される前に発生します。 イベントは Blazor コンポーネントの基底クラスで定義されています。 次の例のようにコード ブロックでそれをオーバーライドできます。
protected override async Task OnInitializedAsync()
{
\\ Call the service here
}
サービスを呼び出してデータを取得する
サービスを呼び出すとき、呼び出しは非同期なので await
キーワードを使用すします。
private Pizza[] todaysPizzas;
protected override async Task OnInitializedAsync()
{
todaysPizzas = await PizzaSvc.GetPizzasAsync();
}
ユーザーにデータを表示する
サービスからデータを取得した後、それをユーザーに表示する必要があります。 このピザの例では、サービスによって、ユーザーが選択できるピザの一覧が返されることを想定しています。 Blazor には、ユーザーに表示されるページに、このデータを挿入するために使用できる豊富なディレクティブのセットが用意されています。
データをチェックする
まず、ピザが読み込まれる前にページに何が表示されるかを確認します。 これを行うには、todaysPizzas
コレクションが null
であるかどうかを確認します。 Blazor コンポーネントで条件付きレンダリング コードを実行するには、@if
ディレクティブを使用します。
@if (todaysPizzas == null)
{
<p>We're finding out what pizzas are available today...</p>
}
else
{
<!-- This markup will be rendered once the pizzas are loaded -->
}
@if
ディレクティブは、C# 式で true
が返された場合にのみ、最初のコード ブロックでマークアップをレンダリングします。 また、else if
コード ブロックを使用して、他のテストを実行し、それらが true の場合にマークアップをレンダリングすることもできます。 最後に、前の条件で true を返すものがなかった場合にコードをレンダリングする else
コード ブロックを指定できます。 @if
コード ブロックで null
をチェックすることにより、サービスからデータが取得される前に、Blazor がピザの詳細を表示しようとしないようにします。
Note
Blazor には、複数の値を返す可能性のあるテストに基づいてマークアップをレンダリングするための @switch
ディレクティブも含まれています。 @switch
ディレクティブは、C# の switch
ステートメントと同じように機能します。
オブジェクトのコレクションをレンダリングする
Blazor で前記のコードの else
ステートメントが実行されると、サービスからいくつかのピザが取得されたことがわかります。 次のタスクは、これらのピザをユーザーに表示することです。 簡単な HTML テーブルにデータを表示する方法を見てみましょう。
このページをコーディングする段階では、表示できるピザの数はわかりません。 @foreach
ディレクティブを使用して、todaysPizzas
コレクション内のすべてのオブジェクトをループ処理し、それぞれに対して 1 行をレンダリングできます。
<table>
<thead>
<tr>
<th>Pizza Name</th>
<th>Description</th>
<th>Vegetarian?</th>
<th>Vegan?</th>
<th>Price</th>
</tr>
</thead>
<tbody>
@foreach (var pizza in todaysPizzas)
{
<tr>
<td>@pizza.Name</td>
<td>@pizza.Description</td>
<td>@pizza.Vegetarian</td>
<td>@pizza.Vegan</td>
<td>@pizza.Price</td>
</tr>
}
</tbody>
</table>
もちろん、この例で示されているような単純なテーブルより、もっと機能豊富なピザの表示がおそらく必要でしょう。 価格やその他の値の書式を設定したいかもしれません。 グラフィック デザイナーと協力して、もっと魅力的な UI を開発します。 たとえば、各ピザの画像を含めます。
Note
Blazor には、@for
、@while
、@do while
など、他にもループ ディレクティブが含まれています。 これらのディレクティブからは、繰り返されるマークアップのブロックが返されます。 これらは、C# の同等の for
、while
、do...while
ループと同じように機能します。
次のユニットでは、独自のデータ サービスを登録します。