ASP.NET Core Blazor WebAssembly の必要最低限のハロー ワールド (イベント対応)
先日、以下のような記事を書いて最低限の ASP.NET Core Blazor WebAssembly でハローワールドを書きました。
今日は、これにもう少しだけ処理を追加してみたいと思います。
まず App.razor
を少し書き換えて App コンポーネントにプロパティを定義します。そのプロパティに Hello world を設定して h3
タグで表示します。
<h3>@Message</h3>
@code {
private string Message { get; set; } = "Hello world";
}
この時点では単純に Hello world のメッセージをプロパティに変えただけです。そして、ボタンを押したら Hello world が「こんにちは世界」に変わるようにしたいと思います。ということで素直にイベントハンドラを作って @onclick
で Message
プロパティの値を置き換えます。(.editorconfig あたりで UTF-8-BOM で保存するようにておかないと後で文字化けするので注意。)
<h3>@Message</h3>
<button @onclick="ToJapanese">To Japanese</button>
@code {
private string Message { get; set; } = "Hello world";
private void ToJapanese() => Message = "こんにちは世界";
}
これを、実行すると無事動きません (!?!?)
イベントを動かすために必要なもの
App.razor
に Microsoft.AspNetCore.Components.Web
の using
を追加するとイベントが使えるようになります。
@using Microsoft.AspNetCore.Components.Web @* これが必要! *@
<h3>@Message</h3>
<button @onclick="ToJapanese">To Japanese</button>
@code {
private string Message { get; set; } = "Hello world";
private void ToJapanese() => Message = "こんにちは世界";
}
実行すると、今度はちゃんと動きました。
ちょっと見てみる
ということで、問題の Microsoft.AspNetCore.Components.Web
名前空間のソースコードを見てみようと思います。
このフォルダーを見てみると、なんとなくイベント関連のクラスが定義されていますが、多分ここにある EventHandlers
クラスにイベント名とイベント引数の型のマッピングが定義されているので、このクラスがいないと onclick
などの基本的なイベントが動かなさそうです。
EventHandlers
という名前のクラスがあると Razor の EventHandlerTagHelperDescriptorProvider
クラスが拾ってくれるところくらいまではわかったのですが、同じコードが Blazor でも動いているかの裏もとってないし、そこからどうなるのか追いかけるのもメンドクサイので諦めました。とりあえず Microsoft.AspNetCore.Components.Web
を using
していないと基本的なタグに対するイベントが動かないということは頭の片隅に入れておきましょう。
プロジェクトテンプレートではどうなってるの…?
_Imports.razor
という特殊な名前のファイルを用意しておくと自動的に、そのファイルがあるのと同じフォルダーとサブフォルダーの .razor
ファイルに含まれます。プロジェクトテンプレートからプロジェクトを作ると、プロジェクトのルートフォルダーに _Imports.razor
というファイルが作られていて、その中に @using Microsoft.AspNetCore.Components.Web
という定義が含まれています。
そのため、プロジェクトテンプレートから作ったら何も考えずに @onclick
などが動くっぽいです。
まとめ
Hello world をベースにプロジェクトいじって遊ぼうと思ったらイベントが動かなかったのでびっくりしました。
でも最終的には動いたのでめでたしめでたし。
Discussion