ola*_*ker 3 async-await blazor
我有这个(简化的)组件,用户输入一个值并按 Enter 键。这应该会导致输入消失,直到进程完成,然后输入应该再次显示。
@if (!commandRunning)
{
<div class="action">
<div class="command">
<span class="symbol">></span>
<input @ref="input" class="in" type="text" @bind-value="@_command" @bind-value:event="oninput" @onkeypress="@(e => KeyPressed(e))">
</div>
</div>
}
@code {
private string _command { get; set; }
private bool commandRunning;
private ElementReference input;
private async Task KeyPressed(KeyboardEventArgs args)
{
if (args.Key == "Enter")
{
commandRunning = true;
await Task.Delay(1000);
commandRunning = false;
await input.FocusAsync();
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这会导致以下错误:
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Unable to focus an invalid element.
Error: Unable to focus an invalid element.
Run Code Online (Sandbox Code Playgroud)
因此,在聚焦点尚未创建输入。
然而,通过在焦点调用之前添加 StateHasChanged() 来更改代码使其可以工作。
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: Unable to focus an invalid element.
Error: Unable to focus an invalid element.
Run Code Online (Sandbox Code Playgroud)
这是预期的行为吗?在执行该方法之前,是否不会在 razor 代码中评估更改的 bool 值?
这是预期的行为吗?
是的。
在像 KeyPressed 这样的事件之前和之后都有一个隐含的 StateHasChanged()。StateHasChanged 将渲染排队,但不会立即执行它。代码路径需要一些await东西才能发生实际的渲染。
因此,当您的方法需要多次“更新”时,您确实需要自己调用它。
在您的解决方案中,渲染是在input.FocusAsync().
为了安全我会选择:
commandRunning = false;
StateHasChanged();
await Task.Delay(1); // allow the rendering to happen
await input.FocusAsync();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2161 次 |
| 最近记录: |