3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

BlazorAdvent Calendar 2023

Day 23

[改訂版] Blazor でラジオボタン input 要素に双方向データバインドする方法

Last updated at Posted at 2023-12-24

素の 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!

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?