如果值在 Blazor 中无效,则重置输入字段值
Reset input field value if value is invalid in Blazor
我在 for 循环中绑定了一些文本字段。
<Input type="text" @onchange='(ChangeEventArgs e)=>DataChange(e,item)' value="@item.value" />
在这里,如果用户在输入字段中键入任何内容,我在 DataChange
函数中有一个自定义验证。
private void DataChange(ChangeEventArgs e, PnL pnl)
{
if(e.Value.ToString().Contains(10))
{
pnl.value = e.Value.ToString();
}
}
如果更改有效,那么我只会为列表中的项目赋值。
但如果它无效我需要将值重置为原始值。
我试过打电话给 StateHasChange()
但没有用。
有人可以帮忙吗?
当@onchange
发生时,绑定已经结束,所以此时无效的字符串在pnl.value
.
其中一个解决方案可能是额外 属性 用于绑定。 value
属性 只有在 tempVal
有效时才会改变,否则会重置 tempVal
:
<input type="text" @bind-value="item.tempVal" />
@code {
PnL item = new() { value = "hello10hi", tempVal = "hello10hi" };//valid values
class PnL
{
public string value { get; set; }
string _tempVal;
public string tempVal { get => _tempVal; set { _tempVal = value; DataChange(value, this); } }
void DataChange(string newVal, PnL pnl)
{
if (newVal.Contains("10"))//is valid
{
pnl.value = newVal;
}
else
{
pnl.tempVal = pnl.value;
}
}
}
}
编辑
(代码已更新)
问题是,tempVal
在写入时没有更新,所以它仍然有默认值,所以在分配value
后没有改变,因此在[=35=中没有更新].
使用 bind-value
,tempVal
将始终更新。 “问题”是我们丢失了 onechange
代码(因为我们使用 bind
)。因此,我不得不与 tempVal
属性.
内部的更改进行交互
试试这个:
private async Task DataChange(ChangeEventArgs e, PnL pnl)
{
if(e.Value.ToString().Contains(10))
{
pnl.value = e.Value.ToString();
}
else
{
var tempValue = pnl.value;
pnl.value = string.Empty();
await Task.Yield();
pnl.value = tempValue;
}
}
所以这里发生的事情是这样的。
- 代码 运行 与
await Task.Yield
同步。
- 此时
pnl.value
为空字符串
DataChange
执行 Blazor 事件处理程序,它将渲染操作加载到渲染器队列。
- Yield 允许渲染器为其渲染队列提供服务,并重新渲染组件。
pnl.value
为空白 - 与上次渲染不同 - 因此输入在 DOM. 中更新
- yield 之后的代码现在 运行 完成,设置
pnl.value
回到它的原始值。
DataChange
完成并且 Blazor 事件处理程序将第二个渲染操作加载到渲染器队列上,该渲染器队列现在在值再次更改时重新渲染输入。
在您的代码中,所有内容 运行 都是同步的。您可以根据需要多次调用 StateHasChanged
,渲染器只会在 运行 完成 DataChange
后获得任务时间。此时渲染器仍然认为输入设置为 pnl.value
的原始值(不是编辑后的值),因此 DOM 不会更新。
CodeProject 上有一篇文章更详细 - https://www.codeproject.com/Articles/5310624/Blazor-UI-Events-and-Rendering
我在 for 循环中绑定了一些文本字段。
<Input type="text" @onchange='(ChangeEventArgs e)=>DataChange(e,item)' value="@item.value" />
在这里,如果用户在输入字段中键入任何内容,我在 DataChange
函数中有一个自定义验证。
private void DataChange(ChangeEventArgs e, PnL pnl)
{
if(e.Value.ToString().Contains(10))
{
pnl.value = e.Value.ToString();
}
}
如果更改有效,那么我只会为列表中的项目赋值。 但如果它无效我需要将值重置为原始值。
我试过打电话给 StateHasChange()
但没有用。
有人可以帮忙吗?
当@onchange
发生时,绑定已经结束,所以此时无效的字符串在pnl.value
.
其中一个解决方案可能是额外 属性 用于绑定。 value
属性 只有在 tempVal
有效时才会改变,否则会重置 tempVal
:
<input type="text" @bind-value="item.tempVal" />
@code {
PnL item = new() { value = "hello10hi", tempVal = "hello10hi" };//valid values
class PnL
{
public string value { get; set; }
string _tempVal;
public string tempVal { get => _tempVal; set { _tempVal = value; DataChange(value, this); } }
void DataChange(string newVal, PnL pnl)
{
if (newVal.Contains("10"))//is valid
{
pnl.value = newVal;
}
else
{
pnl.tempVal = pnl.value;
}
}
}
}
编辑 (代码已更新)
问题是,tempVal
在写入时没有更新,所以它仍然有默认值,所以在分配value
后没有改变,因此在[=35=中没有更新].
使用 bind-value
,tempVal
将始终更新。 “问题”是我们丢失了 onechange
代码(因为我们使用 bind
)。因此,我不得不与 tempVal
属性.
试试这个:
private async Task DataChange(ChangeEventArgs e, PnL pnl)
{
if(e.Value.ToString().Contains(10))
{
pnl.value = e.Value.ToString();
}
else
{
var tempValue = pnl.value;
pnl.value = string.Empty();
await Task.Yield();
pnl.value = tempValue;
}
}
所以这里发生的事情是这样的。
- 代码 运行 与
await Task.Yield
同步。 - 此时
pnl.value
为空字符串 DataChange
执行 Blazor 事件处理程序,它将渲染操作加载到渲染器队列。- Yield 允许渲染器为其渲染队列提供服务,并重新渲染组件。
pnl.value
为空白 - 与上次渲染不同 - 因此输入在 DOM. 中更新
- yield 之后的代码现在 运行 完成,设置
pnl.value
回到它的原始值。 DataChange
完成并且 Blazor 事件处理程序将第二个渲染操作加载到渲染器队列上,该渲染器队列现在在值再次更改时重新渲染输入。
在您的代码中,所有内容 运行 都是同步的。您可以根据需要多次调用 StateHasChanged
,渲染器只会在 运行 完成 DataChange
后获得任务时间。此时渲染器仍然认为输入设置为 pnl.value
的原始值(不是编辑后的值),因此 DOM 不会更新。
CodeProject 上有一篇文章更详细 - https://www.codeproject.com/Articles/5310624/Blazor-UI-Events-and-Rendering