我无法使 .NET 6 的 Blazor AsyncFocus 方法起作用。
据我所知,AsyncFocus 仅在组件值不为空时才起作用。该模型确保组件值不为空。
型号:
namespace BlazorAppWithService.Models;
public class TagModel
{
public string? TagName { get; set; } = "";
}
Blazor 标记:
<EditForm Model="@newTag" OnValidSubmit="AddTag">
<InputText @ref="ele "@bind-Value="newTag.TagName"></InputText>
<button type="submit">Add tag</button>
</EditForm>
此代码:
@code {
InputText ele;
private List<TagModel> tagList = new List<TagModel>();
private TagModel newTag = new TagModel();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
if (ele.Element != null)
await ele.Element.Value.FocusAsync();
}
private async void AddTag()
{
tagList.Add(newTag);
newTag = new TagModel();
if (ele.Element != null)
{
await ele.Element.Value.FocusAsync();
}
}
}
此代码正确地将焦点设置在第一次渲染上,但在调用 AddTag() 方法时组件未获得焦点。
FWIW,这也不会定位光标:
<button @onclick="() => ele.Element.Value.FocusAsync()" type="submit">Add tag</button>
Blazor:让困难的事情变得简单,让简单的事情变得困难!
解释一下到底发生了什么
FocusAsync
正在调用 JavaScript,但 Blazor 会在发生这种情况后重新渲染。因此,您需要在 OnAfterRenderAsync 方法中调用 FocusAsync
,如下所示:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await ele.Element.Value.FocusAsync();
}
可能不太明显
FocusAsync
使用 JavaScript,但这就是它不起作用的原因。关于调用 JavaScript 的文档中有这样一段摘录:
要延迟 JavaScript 互操作调用,直到保证此类调用有效,请覆盖 OnAfterRender{Async} 生命周期 事件。仅在应用程序完全渲染后才会调用此事件。
对我来说,问题是目标元素不存在。想象一下这个场景:
if (ShowInput)
{
<input @ref="MyInput" />
}
@code{
bool ShowInput { get; set; }
ElementReference? MyInput { get; set; }
async Task SomeOperation()
{
ShowInput = true;
//Here, Blazor should render the input, but has not yet. Currently there is no input.
await MyInput.FocusAsync();
}
}
所以我们应该在完全渲染元素后以某种方式调用
FocusAsync
。请注意,像 EditForm
这样的容器组件可能会影响其子组件的渲染行为。 (我相信这是你问题的根源。)