我正在构建一个自定义的Blazor组件,其中@inherits InputBase<string[]>
.
在内部,输入String[]被解析并转换为对象列表。
遍历对象列表,并为每个条目生成输入:
<input type="text" value="@_list[j].Value" @onchange="(e => UpdateItem(j, e))" />
UpdateItem方法做几件事。例如,它更新集合中的项并检查new value是否为空字符串,如果是则从集合中删除项。
然而,当用户在输入文本中添加无效字符时,UpdateItem将它们去掉并执行list[index] = v
,但由于list[index] == v
,它不会更改底层的Item或List。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;
}
}
字符串是对象,但是通过value"传递。问题。
Blazor Renderer。当您创建输入时,它被渲染为
<input value="Australia">
。当用户将其更改为" australia +"时,处理将删除"+"并将其设置为"澳大利亚"。显示值" australia +"只存在于实际的浏览器DOM中,而不存在于Renderer DOM中。渲染器仍然认为它是"澳大利亚",所以不重新渲染它。
我通过将字符串数组设置为有序列表解决了第一个问题。它现在是一个对象,并且有了秩序。
第二个问题我通过检查新值(删除无效字符)是否与旧值相同来解决。如果是,那么我将MyStrings
值设置为无效值,并将控制权交还给任务调度程序。事件处理程序现在在最后的MyStrings[key] = newvalue
代码块运行之前重新呈现组件。最后一次呈现组件,并将正确的值赋给输入。
如果你想了解更多关于Blazor事件过程的信息,你可以在这里阅读更多