输入文本值:恢复到以前的值
input text value: revert to previous value
我正在构建一个自定义 Blazor 组件,@inherits InputBase<string[]>
。
在内部解析输入 String[] 并将其转换为对象列表。
迭代该对象列表并为每个项目生成输入:
<input type="text" value="@_list[j].Value" @onchange="(e => UpdateItem(j, e))" />
UpdateItem 方法做几件事。例如,它更新集合中的项目并检查新值是否为空字符串,如果是则从集合中删除项目。
但是,当用户向输入文本添加无效字符时,UpdateItem 会将它们删除并执行 list[index] = v
,但因为 list[index] == v
它不会更改基础项目或列表。 CurrentValue
保持正确,但界面不更新,例如输入文本保留无效值,这具有误导性。如果我删除该项目并将其插入同一索引,它仍然不起作用。删除和添加它确实更新了界面,但最后添加了项目,这令人困惑。
我尝试在 UpdateItem 方法和其他地方调用 StateHasChanged()
,但没有帮助。
如何“告诉”输入值自行更新?或者我如何“标记”值已更新,尽管它是相同的以触发界面更新。
也许我对这个问题的处理方式完全错误。我从 <input @bind="@_list[j].Value"... />
开始,效果很好,但我需要控制绑定以验证输入并最终更改它。这就是为什么我选择了描述的路线。
我认为有几个问题困扰着您。
首先这是一个工作演示页面,我认为它封装了您要实现的目标:
@page "/StringTester"
<h3>String Test Page</h3>
@foreach (var str in MyStrings)
{
<div class="form">
<input @key="str" class="form-control" value="@str.Value" @onchange="(e) => StringChanged(e, str.Key )" />
</div>
}
@code {
SortedList<int, string> MyStrings = new SortedList<int, string> { { 1, "UK" }, { 2, "Australia" }, { 3, "Spain" } };
string[] invalidchars = { "=", "+" };
// Must be async and Task based for the Yield to work
async Task StringChanged(ChangeEventArgs e, int key)
{
var val = e.Value.ToString();
if (string.IsNullOrEmpty(val))
MyStrings.Remove(key);
else
{
var newvalue = InvalidCharStripper(val);
if (MyStrings[key].Equals(newvalue))
{
MyStrings[key] = val;
await Task.Yield();
}
MyStrings[key] = newvalue;
}
}
// quick and dirty method to do some input manipulation - remove invalid chars from the string
string InvalidCharStripper(string value)
{
foreach (var x in invalidchars)
{
value = value.Replace(x, string.Empty);
}
return value;
}
}
“字符串是对象,但按值传递”问题。
Blazor 渲染器。当您创建输入时,它会呈现为 <input value="Australia">
。当用户将其更改为“Austalia+”时,处理会删除“+”并将其设置为“Australia”。显示值“Austalia+”仅存在于实际浏览器DOM,而不存在于渲染器DOM。渲染器仍然认为它是“澳大利亚”,因此不会重新渲染它。
我已经通过将字符串数组设置为有序列表解决了第一个问题。它现在是一个对象并且有秩序。
我通过检查新值(删除了无效字符)是否与旧值相同来解决了第二个问题。如果是,那么我将 MyStrings
值设置为无效值,并将 Yield 控制返回给任务调度程序。事件处理程序现在在最终 MyStrings[key] = newvalue
代码块运行之前重新呈现组件。最后一次渲染组件,并为输入分配正确的值。
如果您想了解更多关于 Blazor 事件流程的信息,可以阅读更多内容 here
我正在构建一个自定义 Blazor 组件,@inherits InputBase<string[]>
。
在内部解析输入 String[] 并将其转换为对象列表。
迭代该对象列表并为每个项目生成输入:
<input type="text" value="@_list[j].Value" @onchange="(e => UpdateItem(j, e))" />
UpdateItem 方法做几件事。例如,它更新集合中的项目并检查新值是否为空字符串,如果是则从集合中删除项目。
但是,当用户向输入文本添加无效字符时,UpdateItem 会将它们删除并执行 list[index] = v
,但因为 list[index] == v
它不会更改基础项目或列表。 CurrentValue
保持正确,但界面不更新,例如输入文本保留无效值,这具有误导性。如果我删除该项目并将其插入同一索引,它仍然不起作用。删除和添加它确实更新了界面,但最后添加了项目,这令人困惑。
我尝试在 UpdateItem 方法和其他地方调用 StateHasChanged()
,但没有帮助。
如何“告诉”输入值自行更新?或者我如何“标记”值已更新,尽管它是相同的以触发界面更新。
也许我对这个问题的处理方式完全错误。我从 <input @bind="@_list[j].Value"... />
开始,效果很好,但我需要控制绑定以验证输入并最终更改它。这就是为什么我选择了描述的路线。
我认为有几个问题困扰着您。
首先这是一个工作演示页面,我认为它封装了您要实现的目标:
@page "/StringTester"
<h3>String Test Page</h3>
@foreach (var str in MyStrings)
{
<div class="form">
<input @key="str" class="form-control" value="@str.Value" @onchange="(e) => StringChanged(e, str.Key )" />
</div>
}
@code {
SortedList<int, string> MyStrings = new SortedList<int, string> { { 1, "UK" }, { 2, "Australia" }, { 3, "Spain" } };
string[] invalidchars = { "=", "+" };
// Must be async and Task based for the Yield to work
async Task StringChanged(ChangeEventArgs e, int key)
{
var val = e.Value.ToString();
if (string.IsNullOrEmpty(val))
MyStrings.Remove(key);
else
{
var newvalue = InvalidCharStripper(val);
if (MyStrings[key].Equals(newvalue))
{
MyStrings[key] = val;
await Task.Yield();
}
MyStrings[key] = newvalue;
}
}
// quick and dirty method to do some input manipulation - remove invalid chars from the string
string InvalidCharStripper(string value)
{
foreach (var x in invalidchars)
{
value = value.Replace(x, string.Empty);
}
return value;
}
}
“字符串是对象,但按值传递”问题。
Blazor 渲染器。当您创建输入时,它会呈现为
<input value="Australia">
。当用户将其更改为“Austalia+”时,处理会删除“+”并将其设置为“Australia”。显示值“Austalia+”仅存在于实际浏览器DOM,而不存在于渲染器DOM。渲染器仍然认为它是“澳大利亚”,因此不会重新渲染它。
我已经通过将字符串数组设置为有序列表解决了第一个问题。它现在是一个对象并且有秩序。
我通过检查新值(删除了无效字符)是否与旧值相同来解决了第二个问题。如果是,那么我将 MyStrings
值设置为无效值,并将 Yield 控制返回给任务调度程序。事件处理程序现在在最终 MyStrings[key] = newvalue
代码块运行之前重新呈现组件。最后一次渲染组件,并为输入分配正确的值。
如果您想了解更多关于 Blazor 事件流程的信息,可以阅读更多内容 here