英文:
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:
<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; }
}
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
你可以使用get
和set
来创建一个新的属性:
<InputRadioGroup @bind-Value="SelectedValue">
<InputRadio Value="1">选项 1</InputRadio>
<InputRadio Value="2">选项 2</InputRadio>
<InputRadio Value="3">选项 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相同的目的,但仅在.NET 7及更高版本中可用,并且在早期版本中存在已知问题,使其无法使用,您必须使用已修复该问题的VS版本。问题修复链接。
英文:
You can use a new property with get
and set
:
<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; }
}
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 "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
欢迎来到您的新应用程序。
<div class="m-2">
<InputRadioGroup @bind-Value:get=_selectedValue @bind-Value:set=ValueSet>
<InputRadio Value="1">选项1</InputRadio>
<InputRadio Value="2">选项2</InputRadio>
<InputRadio Value="3">选项3</InputRadio>
</InputRadioGroup>
</div>
<div class="m-2">
<InputRadioGroup @bind-Value=_selectedValue @bind-Value:after=ValueSet>
<InputRadio Value="1">选项1</InputRadio>
<InputRadio Value="2">选项2</InputRadio>
<InputRadio Value="3">选项3</InputRadio>
</InputRadioGroup>
</div>
<div class="bg-dark text-white m-2 p-2">
<pre>值 : @_selectedValue</pre>
<pre>状态: @(_isDirty? "已更改" : "未更改")</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;
}
}
英文:
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 "/"
<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;
}
}
答案3
得分: 0
以下是您要翻译的内容:
"由于您显然正在尝试跟踪状态,这里提供了一种使用编辑上下文对象和记录的不同方法。无需手动设置或取消设置IsDirty
:编辑上下文会自动跟踪状态。
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
欢迎来到您的新应用程序。
<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);
}
// 将所有数据视为不可变
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 => new()
{
Value = this.Value
};
public bool IsDirty => 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 "/"
<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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论