この記事には以下の改訂版がありますので、最新の情報は下記を参照ください。
[改訂版] Blazor でラジオボタン input 要素に双方向データバインドする方法
https://qiita.com/jsakamoto/items/a326ddb14b0a7b6c4a74
その前に: "Blazor" とは?
"Blazor" とは、シングルページ Web アプリケーション (いわゆる "SPA") フレームワークです。
Blazor は、C# コードおよび .NET Standard 2.0 のネイティブアセンブリ (.dll) を、.NET サーバープロセスを使用せずに、モダン Web ブラウザ上で実行します。
もし Blazor について初めての方は、手前味噌ながら下記ポストをご覧頂くとよいかと思います。
C# で Single Page Web Application が書ける Blazor が凄かった件
Blazor における双方向データバインド
Blazor は SPA フレームワークですから、下記のとおり容易に、データと input 要素・select/option 要素とを、双方向データバインドすることができます。
@functions {
int EditionCode = 1;
}
<select bind="@EditionCode">
<option value="1">Home</option>
<option value="2">Pro</option>
<option value="3">Enterprise</option>
</select>
Blazor は双方向データバインドの仕組みを "bind=..." 構文として提供しています。
"bind" 構文がラジオボタン input 要素で機能しない!
しかしながら例外的に、現時点での Blazor (v.0.5.x) では、ラジオボタン input 要素に "bind=..." 構文で双方向データバインドすることができません。
以下のサンプルコードは機能しません。
@functions {
int EditionCode = 1;
}
<label>
<input type="radio" value="1" bind="@EditionCode"/> Home
</label>
<label>
<input type="radio" value="2" bind="@EditionCode"/> Pro
</label>
<label>
<input type="radio" value="3" bind="@EditionCode"/> Enterprise
</label>
近い将来、上記コードが機能するようになるとは思います。
しかし Blazor v.0.5.x ではまだ対応されていません。
どうしたらよいでしょう!?
この問題の回避策
ご心配いりません。回避策があります。
ラジオボタン input 要素に対する双方向データバインドは、以下のとおり実装できます。
@functions {
int EditionCode = 1;
}
<label>
<input type="radio" checked="@(EditionCode == 1)" onchange="@(() => EditionCode = 1)"/> Home
</label>
<label>
<input type="radio" checked="@(EditionCode == 2)" onchange="@(() => EditionCode = 2)"/> Pro
</label>
<label>
<input type="radio" checked="@(EditionCode == 3)" onchange="@(() => EditionCode = 3)"/> Enterprise
</label>
checked="@(EditionCode == ...)"
というコードは、"データから DOM へ" の一方向データバインドとして機能します。
他方、 onchage="@(() => EditionCode = ...)"
というコードは、"DOM からデータへ" の一方向データバインドとして機能します。
この2つのコードを組み合わせることで、ラジオボタン input 要素に対する双方向データバインドを実装できます。
もちろん、下記のとおり、ラジオボタン input 要素を動的に構築することもできます。
@functions {
int EditionCode = 1;
// "Edition" class has "int Code" and "string Text" properties.
Edition[] Editions = new [] {
new Edition { Code = 1, Text = "Home" },
new Edition { Code = 2, Text = "Pro" },
new Edition { Code = 3, Text = "Enterprise" },
};
}
@foreach (var edition in this.Editions)
{
<label>
<input type="radio"
checked="@(EditionCode == edition.Code)"
onchange="@(() => EditionCode = edition.Code)"/>
@edition.Text
</label>
}
この回避策はやや冗長であまり格好良くはありません。
が、兎に角、正しく機能します。
いずれ将来バージョンの Blazor は、ラジオボタン input 要素の "bind=..." 構文をサポートすることと思います。
下記の Isseue もお見逃しなく。
Blazor の新バージョンリリースが楽しみですね!
Happy coding with Blazor :)