演習 - データ バインディングとイベント
この演習では、Blazor アプリ内に基本的な Todo リスト コンポーネントを作成します。
Todo ページを作成する
[Todo] ページを作成します。
Visual Studio で、[ソリューション エクスプローラー] の
Components/Pages
フォルダーを右クリックし、[追加]>[Razor コンポーネント] を選択します。 コンポーネントにTodo.razor
という名前を付けます。Visual Studio Code 内で、ソリューション エクスプローラー内の [
Pages
] フォルダーを右クリックし、[新しいファイルの追加...]>[Razor コンポーネント] を選択します。 コンポーネントにTodo.razor
という名前を付けます。 そのファイルは [Pages
] フォルダー内に作成される必要があります重要
Razor コンポーネント ファイル名の先頭文字は、大文字である必要があります。
Pages
フォルダーを展開して、Todo
コンポーネントのファイル名が大文字のT
で始まっていることを確認します。 ファイル名はTodo.razor
のはずです。Todo
コンポーネントを開き、/todo
の相対 URL を使用して、ファイルの先頭に@page
Razor ディレクティブを追加します。@page "/todo" <h3>Todo</h3> @code { }
Components/Pages/Todo.razor
ファイルを保存します。
Todo コンポーネントをナビゲーション バーに追加する
アプリのレイアウトでは NavMenu
コンポーネントを使用します。 レイアウトは、アプリ内でのコンテンツの重複を回避できるようにするコンポーネントです。 NavLink
コンポーネントによって HTML アンカー タグがレンダリングされるので、アプリの URL がリンクと一致したときにアプリの UI で合図を出せるようにこのタグのスタイルを設定できます。
ソリューション エクスプローラーで Components/Layout フォルダーを展開し、NavMenu.razor ファイルを開きます。 NavMenu コンポーネントの <nav>...</nav>
セクションに、次の新しい <div>...</div>
と、Todo
コンポーネントに対する NavLink
コンポーネントを追加します。
Components/Layout/NavMenu.razor
:
<!-- .. -->
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<!-- ... -->
<div class="nav-item px-3">
<NavLink class="nav-link" href="todo">
<span class="bi bi-list-nested-nav-menu" aria-hidden="true"></span> Todo
</NavLink>
</div>
</nav>
</div>
Components/Layout//NavMenu.razor
ファイルを保存します。 ブラウザーが自動的に更新され、ナビゲーション バーに Todo エントリが表示されるようになりました。
Todo 項目を作成する
ソリューション エクスプローラーでプロジェクトを右クリックし、[追加]>[新しいフォルダー] を選択します。 新しいフォルダーに Data という名前を付けます。
ソリューション エクスプローラーで、Data フォルダーを右クリックしてから、[追加]>[クラス] を選択します。 新しいクラスに TodoItem.cs という名前を付けてから、[追加] を選択します。 この新しいクラスは、todo 項目を表す C# クラスを保持します。
7 行目以降のコードを、TodoItem
クラス用の次の C# コードに置き換えます。 ?
を使用して、Title
を null 許容文字列として宣言します。 ファイルを保存します。
namespace BlazorHybridApp.Data;
public class TodoItem
{
public string? Title { get; set; }
public bool IsDone { get; set; } = false;
}
TodoItems のリストをバインドする
以上で、TodoItem
オブジェクトのコレクションを Blazor で HTML にバインドできるようになりました。 Components/Pages/Todo.razor
ファイルで以下の変更を行うことで、これを実現します。
@using BlazorHybridApp.Data
を使用してTodoItem
の using 宣言を追加します。- Todo アイテム用のフィールドを
@code
ブロックに追加します。Todo
コンポーネントでは、このフィールドを使って ToDo リストの状態を維持します。 - 各 Todo アイテムをリスト アイテム (
<li>
) としてレンダリングするために、順序のないリストのマークアップとforeach
ループを追加します。
@page "/todo"
@using BlazorHybridApp.Data
<h3>Todo</h3>
<ul class="list-unstyled">
@foreach (var todo in todos)
{
<li>@todo.Title</li>
}
</ul>
@code {
private List<TodoItem> todos = new();
}
Todo を作成するためのフォーム要素を追加する
アプリには、リストに Todo 項目を追加するための UI 要素が必要です。 順序のないリスト (
<ul>...</ul>
) の下に、テキスト入力 (<input>
) とボタン (<button>
) を追加します。@page "/todo" @using BlazorHybridApp.Data <h3>Todo</h3> <ul class="list-unstyled"> @foreach (var todo in todos) { <li>@todo.Title</li> } </ul> <input placeholder="Something todo" /> <button>Add todo</button> @code { private List<TodoItem> todos = new(); }
Add todo
ボタンを選択しても何も起こりません。ボタンにイベント ハンドラーがアタッチされていないためです。Todo
コンポーネントにAddTodo
メソッドを追加し、@onclick
属性を使用して、そのメソッドをボタン用に登録します。 ボタンを選択すると C# のメソッドAddTodo
が呼び出されます。<input placeholder="Something todo" /> <button @onclick="AddTodo">Add todo</button> @code { private List<TodoItem> todos = new(); private void AddTodo() { // Todo: Add the todo } }
新しい Todo アイテムのタイトルを取得するには、
@code
ブロックの先頭にnewTodo
文字列フィールドを追加します。@code { private List<TodoItem> todos = new(); private string? newTodo; // Omitted for brevity... }
@bind
属性を使用して、newTodo
をバインドするように<input>
要素を変更します。<input placeholder="Something todo" @bind="newTodo" />
指定したタイトルを備えた
TodoItem
をリストに追加するように、AddTodo
メソッドを更新します。newTodo
を空の文字列に設定して、テキスト入力の値をクリアします。@page "/todo" @using BlazorHybridApp.Data <h3>Todo</h3> <ul class="list-unstyled"> @foreach (var todo in todos) { <li>@todo.Title</li> } </ul> <input placeholder="Something todo" @bind="newTodo" /> <button @onclick="AddTodo">Add todo</button> @code { private List<TodoItem> todos = new(); private string? newTodo; private void AddTodo() { if (!string.IsNullOrWhiteSpace(newTodo)) { todos.Add(new TodoItem { Title = newTodo }); newTodo = string.Empty; } } }
Components/Pages/Todo.razor
ファイルを保存します。 アプリをリビルドして再起動します。各 todo のタイトル テキストは編集可能にすることができ、チェックボックスは完了した項目をユーザーが追跡するのに役立ちます。 各 Todo アイテムにチェックボックス入力を追加し、その値を
IsDone
プロパティにバインドします。@todo.Title
を、@bind
でtodo.Title
にバインドされた<input>
要素に変更します。<ul class="list-unstyled"> @foreach (var todo in todos) { <li> <input type="checkbox" @bind="todo.IsDone" /> <input @bind="todo.Title" /> </li> } </ul>
<h3>
ヘッダーを更新し、完了していない (IsDone
がfalse
の) Todo アイテムの数のカウントを表示するようにします。<h3>Todo (@todos.Count(todo => !todo.IsDone))</h3>
Components/Pages/Todo.razor
ファイルを保存し、もう一度アプリを実行します。コンポーネントをテストするために、項目を追加し、項目を編集し、項目を完了としてマークします。