素の input 要素を相手にする限りは 2023年12月現在も変わりありません
Blazor がまだ v.0.5 (!) だった頃、以下の記事を書きました。
上記記事は 2023年12月現在、かれこれ 6 年近く前の記事となります。本記事では、Blazor が公式リリース後に、ラジオボタン input 要素に双方向データバインドする方法がどうなったのか、確認します。
まず、以下のようについ書きたくなるコードは、引き続き残念ながら、
Eerror RZ10008: The attribute 'value' is used two or more times for this element. Attributes must be unique (case-insensitive). The attribute 'value' is used by the '@bind' directive attribute.
というビルドエラーになり、ビルドすら通りません。
<-- 👇これはビルドエラーになります -->
<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>
@code {
private int _editionCode = 1;
}
@bind
構文について、下手に対象要素に応じて挙動を変えることは返って問題を増やすのみと判断されたのでしょう、Blazor としては @bind
構文の振る舞いは一貫性が保たれていることから上記エラーとなるようです。
すなわち、@bind
構文は、言ってみればある種の糖衣構文のようなものですから、件の 6 年前の記事のように、自前で "モデルから UI へ" の方向と "UI からモデルへ" の方向のバインド処理を記述することで、ひとまず正解となります (下記コード)。
<-- 👇これで正常に動作します -->
<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>
@code {
private int _editionCode = 1;
}
.NET 5 以降は、簡単に書けるようになりました
さて、件の記事作成後、Blazor が 2019年9月に .NET Core 3.0 リリースで公式リリースになったさらにその後、2020年11月の .NET 5 リリースで、新しい標準添付のコンポーネント InputRadioGroup
および InputRadio
コンポーネントがリリースされました。InputRadioGroup
および InputRadio
コンポーネントを使うと、以下のように書けるようになります。
<InputRadioGroup @bind-Value="_editionCode">
<label>
<InputRadio Value="1" />Home
</label>
<label>
<InputRadio Value="2" />Pro
</label>
<label>
<InputRadio Value="3" />Enterprise
</label>
</InputRadioGroup>
@code {
private int _editionCode = 1;
}
特に説明も要らないくらいシンプルですね!
あと、これまでのサンプルコードでは、簡略化のためにちょっとサボっているところがあって、それは <input type="radio".../>
要素に name
属性を明示していませんでした。このサンプルの程度ではそれなりに動いてしまうのですけど、<input type="radio".../>
要素は、同じ name
属性値をもつ要素間でチェック状態が排他になるので、実際にはちゃんとページ内でユニークなグループになるよう name
属性値を設定する必要があります。
その点、この Blazor に標準添付されている InputRadioGroup
および InputRadio
コンポーネントは、Name
パラメーターを明示しないときは、GUID 値に基づく name
属性値を自動で付与してくれます。なので、とくに name
属性をなんとするか気にせずに実装できるのも嬉しいポイントです。
まとめ
ということで、Blazor でラジオボタン input 要素に双方向データバインドするには、Blazor に標準添付されている InputRadioGroup
および InputRadio
コンポーネントを使いましょう。
Learn, Practice, Share!