.net 无法在Blazor Server应用程序中激发InputRadio的onchange事件

8ehkhllq  于 2023-06-07  发布在  .NET
关注(0)|答案(3)|浏览(800)

在Blazor服务器页面中,我找不到任何方法来检测何时选择了无线电组中的不同无线电项目。
下面是一个onchange事件永远不起作用的示例:

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

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

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

j8yoct9x

j8yoct9x1#

您可以使用getset的新属性:

<InputRadioGroup @bind-Value="SelectedValue">
    <InputRadio Value="1">Option 1</InputRadio>
    <InputRadio Value="2">Option 2</InputRadio>
    <InputRadio Value="3">Option 3</InputRadio>
</InputRadioGroup>

@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相同的目的,但是它只能从.Net7中获得,并且其早期版本存在已知问题,无法使用,您必须使用具有issue fixed的VS版本。
f5emj3cl

f5emj3cl2#

下面是代码的一个工作示例,展示了实现所需目标的两种方法。我不使用lambda匿名方法,因为它们很昂贵:它们必须在每次组件渲染时创建。
所有事件都在InputRadioGroup组件上触发,而不是单个项目:它是一个组件,而不是一组未链接的元素。

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="m-2">
    <InputRadioGroup @bind-Value:get=_selectedValue @bind-Value:set=ValueSet>
        <InputRadio Value="1">Option 1</InputRadio>
        <InputRadio Value="2">Option 2</InputRadio>
        <InputRadio Value="3">Option 3</InputRadio>
    </InputRadioGroup>
</div>

<div class="m-2">
    <InputRadioGroup @bind-Value=_selectedValue @bind-Value:after=ValueSet>
        <InputRadio Value="1">Option 1</InputRadio>
        <InputRadio Value="2">Option 2</InputRadio>
        <InputRadio Value="3">Option 3</InputRadio>
    </InputRadioGroup>
</div>

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

    private bool _isDirty { get; set; }

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

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

dxxyhpgq3#

由于您显然试图跟踪状态,因此这里有一种使用编辑上下文对象和记录的不同方法。无需手动设置或取消设置IsDirty:编辑上下文自动跟踪状态。

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="m-2">
    <InputRadioGroup @bind-Value=_recordEditContext.Value>
        <InputRadio Value=1>Option 1</InputRadio>
        <InputRadio Value=2>Option 2</InputRadio>
        <InputRadio Value=3>Option 3</InputRadio>
    </InputRadioGroup>
</div>

<div class="bg-dark text-white m-2 p-2">
    <pre>Value : @_recordEditContext.Value</pre>
    <pre>State: @(_recordEditContext.IsDirty? "Dirty" : "Clean")</pre>
</div>
@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 => new()
        {
            Value = this.Value
        };

        public bool IsDirty => this.BaseRecord != this.AsRecord;
    }
}

相关问题