在Blazor服务器应用程序中无法触发InputRadio的onchange事件。

huangapple go评论66阅读模式
英文:

Cannot fire onchange event for InputRadio in Blazor Server app

问题

在Blazor Server页面中,我无法找到任何检测不同单选按钮项在单选按钮组中被选择的方法。

以下是一个示例,其中onchange事件从不起作用:

<InputRadioGroup @bind-Value="selectedValue">
    <InputRadio Value="1" @onchange="() => IsDirty = true">选项 1</InputRadio>
    <InputRadio Value="2" @onchange="() => IsDirty = true">选项 2</InputRadio>
    <InputRadio Value="3" @onchange="() => IsDirty = true">选项 3</InputRadio>
</InputRadioGroup>

@code 
{
    private string selectedValue;
    private bool IsDirty { get; set; }
}

在Blazor Server中是否有一种设置IsDirty标志的方法?这是使用dotnet new blazorserver-empty生成的dotnet 7模板项目。

英文:

In a Blazor Server page I can't find any way of detecting when a different radio item in the radio group has been selected.

Here's an example where the onchange event never works:

&lt;InputRadioGroup @bind-Value=&quot;selectedValue&quot;&gt;
    &lt;InputRadio Value=&quot;1&quot; @onchange=&quot;()=&gt;IsDirty = true&quot;&gt;Option 1&lt;/InputRadio&gt;
    &lt;InputRadio Value=&quot;2&quot; @onchange=&quot;()=&gt;IsDirty = true&quot;&gt;Option 2&lt;/InputRadio&gt;
    &lt;InputRadio Value=&quot;3&quot; @onchange=&quot;()=&gt;IsDirty = true&quot;&gt;Option 3&lt;/InputRadio&gt;
&lt;/InputRadioGroup&gt;

@code 
{
    private string selectedValue;
    private bool IsDirty { get; set; }
}

Is there a way to set the IsDirty flag in Blazor Server?

This is dotnet 7 using dotnet new blazorserver-empty to generate the template project.

答案1

得分: 2

你可以使用getset来创建一个新的属性:

&lt;InputRadioGroup @bind-Value=&quot;SelectedValue&quot;&gt;
    &lt;InputRadio Value=&quot;1&quot;&gt;选项 1&lt;/InputRadio&gt;
    &lt;InputRadio Value=&quot;2&quot;&gt;选项 2&lt;/InputRadio&gt;
    &lt;InputRadio Value=&quot;3&quot;&gt;选项 3&lt;/InputRadio&gt;
&lt;/InputRadioGroup&gt;

@code 
{
    private string selectedValue;
    public string SelectedValue 
    { 
        get { return selectedValue; } 
        set { selectedValue = value; IsDirty = true;}
    }

    private bool IsDirty { get; set; }
}

但要注意一些事项:

  • 在初始化selectedValue时,不要使用该属性,因为这样会同时设置布尔值。
  • 布尔值仅表示该值在某个时刻已更改,但并不表示该值与其原始值是否不同。
  • @bind:set@bind:get@bind:after可以用于与@MrCakaShaunCurtis相同的目的,但仅在.NET 7及更高版本中可用,并且在早期版本中存在已知问题,使其无法使用,您必须使用已修复该问题的VS版本。问题修复链接
英文:

You can use a new property with get and set:

&lt;InputRadioGroup @bind-Value=&quot;SelectedValue&quot;&gt;
    &lt;InputRadio Value=&quot;1&quot;&gt;Option 1&lt;/InputRadio&gt;
    &lt;InputRadio Value=&quot;2&quot;&gt;Option 2&lt;/InputRadio&gt;
    &lt;InputRadio Value=&quot;3&quot;&gt;Option 3&lt;/InputRadio&gt;
&lt;/InputRadioGroup&gt;

@code 
{
    private string selectedValue;
    public string SelectedValue 
    { 
        get { return selectedValue; } 
        set { selectedValue = value; IsDirty = true;}
    }

    private bool IsDirty { get; set; }
}

However, be aware of a few things :

  • When initializing selectedValue, don't use the property because you would set the boolean as well.
  • The boolean just states that the value has been changed at some point, but it does not tell if the value differs from its original value.
  • @bind:set, @bind:get and @bind:after can be used for the same purpose as in @MrCakaShaunCurtis, however it is only available from .Net7 and have a known issue for its early versions making it impossible to use, you must use a VS version that has the issue fixed.

答案2

得分: 1

以下是您的代码的翻译部分:

这是您的代码的工作示例,展示了实现您想要的两种方法。我没有使用lambda匿名方法,因为它们开销较大:它们必须在每次组件渲染时创建。

所有事件都在InputRadioGroup组件上触发,而不是在单独的项上:它是一个组件,而不是一组不相关的元素。

@page &quot;/&quot;

&lt;PageTitle&gt;Index&lt;/PageTitle&gt;

&lt;h1&gt;Hello, world!&lt;/h1&gt;

欢迎来到您的新应用程序。

&lt;div class=&quot;m-2&quot;&gt;
    &lt;InputRadioGroup @bind-Value:get=_selectedValue @bind-Value:set=ValueSet&gt;
        &lt;InputRadio Value=&quot;1&quot;&gt;选项1&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;2&quot;&gt;选项2&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;3&quot;&gt;选项3&lt;/InputRadio&gt;
    &lt;/InputRadioGroup&gt;
&lt;/div&gt;

&lt;div class=&quot;m-2&quot;&gt;
    &lt;InputRadioGroup @bind-Value=_selectedValue @bind-Value:after=ValueSet&gt;
        &lt;InputRadio Value=&quot;1&quot;&gt;选项1&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;2&quot;&gt;选项2&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;3&quot;&gt;选项3&lt;/InputRadio&gt;
    &lt;/InputRadioGroup&gt;
&lt;/div&gt;

&lt;div class=&quot;bg-dark text-white m-2 p-2&quot;&gt;
    &lt;pre&gt; : @_selectedValue&lt;/pre&gt;
    &lt;pre&gt;状态: @(_isDirty? &quot;已更改&quot; : &quot;未更改&quot;)&lt;/pre&gt;
&lt;/div&gt;
@code
{
    private string? _selectedValue;

    private bool _isDirty { get; set; }

    private void ValueSet(string? value)
    {
        _isDirty = true;
        _selectedValue = value;
    }

    private void ValueSet()
    {
        _isDirty = true;
    }
}
英文:

Here's a working example of your code, showing two ways to achieve what you want. I don't use lambda anonymous methods as they are expensive: they have to be created every time the component renders.

The events are all triggered on the InputRadioGroup component, not the individual items: it's a component, not a group of unlinked elements.

@page &quot;/&quot;

&lt;PageTitle&gt;Index&lt;/PageTitle&gt;

&lt;h1&gt;Hello, world!&lt;/h1&gt;

Welcome to your new app.

&lt;div class=&quot;m-2&quot;&gt;
    &lt;InputRadioGroup @bind-Value:get=_selectedValue @bind-Value:set=ValueSet&gt;
        &lt;InputRadio Value=&quot;1&quot;&gt;Option 1&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;2&quot;&gt;Option 2&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;3&quot;&gt;Option 3&lt;/InputRadio&gt;
    &lt;/InputRadioGroup&gt;
&lt;/div&gt;

&lt;div class=&quot;m-2&quot;&gt;
    &lt;InputRadioGroup @bind-Value=_selectedValue @bind-Value:after=ValueSet&gt;
        &lt;InputRadio Value=&quot;1&quot;&gt;Option 1&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;2&quot;&gt;Option 2&lt;/InputRadio&gt;
        &lt;InputRadio Value=&quot;3&quot;&gt;Option 3&lt;/InputRadio&gt;
    &lt;/InputRadioGroup&gt;
&lt;/div&gt;

&lt;div class=&quot;bg-dark text-white m-2 p-2&quot;&gt;
    &lt;pre&gt;Value : @_selectedValue&lt;/pre&gt;
    &lt;pre&gt;State: @(_isDirty? &quot;Dirty&quot; : &quot;Clean&quot;)&lt;/pre&gt;
&lt;/div&gt;
@code
{
    private string? _selectedValue;

    private bool _isDirty { get; set; }

    private void ValueSet(string? value)
    {
        _isDirty = true;
        _selectedValue = value;
    }

    private void ValueSet()
    {
        _isDirty = true;
    }
}

答案3

得分: 0

以下是您要翻译的内容:

"由于您显然正在尝试跟踪状态,这里提供了一种使用编辑上下文对象和记录的不同方法。无需手动设置或取消设置IsDirty:编辑上下文会自动跟踪状态。

@page &quot;/&quot;

&lt;PageTitle&gt;Index&lt;/PageTitle&gt;

&lt;h1&gt;Hello, world!&lt;/h1&gt;

欢迎来到您的新应用程序。

&lt;div class=&quot;m-2&quot;&gt;
    &lt;InputRadioGroup @bind-Value=_recordEditContext.Value&gt;
        &lt;InputRadio Value=1&gt;Option 1&lt;/InputRadio&gt;
        &lt;InputRadio Value=2&gt;Option 2&lt;/InputRadio&gt;
        &lt;InputRadio Value=3&gt;Option 3&lt;/InputRadio&gt;
    &lt;/InputRadioGroup&gt;
&lt;/div&gt;

&lt;div class=&quot;bg-dark text-white m-2 p-2&quot;&gt;
    &lt;pre&gt;Value : @_recordEditContext.Value&lt;/pre&gt;
    &lt;pre&gt;State: @(_recordEditContext.IsDirty? &quot;Dirty&quot; : &quot;Clean&quot;)&lt;/pre&gt;
&lt;/div&gt;
@code
{
    private Model _model = new() {Value=2 };
    private ModelEditContext _recordEditContext = new(new());

    protected override void OnInitialized()
    {
        _recordEditContext = new(_model);
    }

    // 将所有数据视为不可变
    public record Model {
        public int Value { get; init; }
    }

    // 为记录创建编辑上下文:
    //  - 跟踪状态
    //  - 提供一个表示传递回数据存储的新状态的记录
    public class ModelEditContext
    {
        public Model BaseRecord { get; private set; }
        public int Value { get; set; }

        public ModelEditContext(Model model)
        {
            this.BaseRecord = model;
            this.Value = model.Value;
        }

        public Model AsRecord =&gt; new()
        {
            Value = this.Value
        };

        public bool IsDirty =&gt; this.BaseRecord != this.AsRecord;
    }
}

希望这对您有所帮助。

英文:

As you are obviously trying to track state then here's a different approach using an edit context object and records. There's no need to manually set or unset IsDirty: the edit context tracks state automatically.

@page &quot;/&quot;

&lt;PageTitle&gt;Index&lt;/PageTitle&gt;

&lt;h1&gt;Hello, world!&lt;/h1&gt;

Welcome to your new app.

&lt;div class=&quot;m-2&quot;&gt;
    &lt;InputRadioGroup @bind-Value=_recordEditContext.Value&gt;
        &lt;InputRadio Value=1&gt;Option 1&lt;/InputRadio&gt;
        &lt;InputRadio Value=2&gt;Option 2&lt;/InputRadio&gt;
        &lt;InputRadio Value=3&gt;Option 3&lt;/InputRadio&gt;
    &lt;/InputRadioGroup&gt;
&lt;/div&gt;

&lt;div class=&quot;bg-dark text-white m-2 p-2&quot;&gt;
    &lt;pre&gt;Value : @_recordEditContext.Value&lt;/pre&gt;
    &lt;pre&gt;State: @(_recordEditContext.IsDirty? &quot;Dirty&quot; : &quot;Clean&quot;)&lt;/pre&gt;
&lt;/div&gt;
@code
{
    private Model _model = new() {Value=2 };
    private ModelEditContext _recordEditContext = new(new());

    protected override void OnInitialized()
    {
        _recordEditContext = new(_model);
    }

    // Treat all data as immutable
    public record Model {
        public int Value { get; init; }
    }

    // Create an edit context for the record:
    //  - that tracks the state 
    //  - provides a record representing the new state for passing back to the data store 
    public class ModelEditContext
    {
        public Model BaseRecord { get; private set; }
        public int Value { get; set; }

        public ModelEditContext(Model model)
        {
            this.BaseRecord = model;
            this.Value = model.Value;
        }

        public Model AsRecord =&gt; new()
        {
            Value = this.Value
        };

        public bool IsDirty =&gt; this.BaseRecord != this.AsRecord;
    }
}

huangapple
  • 本文由 发表于 2023年5月31日 23:03:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76374909.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定