Blazor 的 FocusAsync 并不总是设置焦点

rp.*_*rp. 6 blazor blazor-server-side

我无法使 .NET 6 的 Blazor AsyncFocus 方法起作用。

据我所知,AsyncFocus 仅在组件值不为空时才起作用。该模型确保组件值不为空。

模型:

namespace BlazorAppWithService.Models;

public class TagModel
{
    public string? TagName { get; set; } = "";
}
Run Code Online (Sandbox Code Playgroud)

Blazor 标记:

<EditForm Model="@newTag" OnValidSubmit="AddTag">
    <InputText @ref="ele "@bind-Value="newTag.TagName"></InputText>
    <button type="submit">Add tag</button>
</EditForm>
Run Code Online (Sandbox Code Playgroud)

这段代码:

@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();            
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码正确地将焦点设置在第一次渲染上,但在调用 AddTag() 方法时组件未获得焦点。

FWIW,这也不定位光标:

<button @onclick="() => ele.Element.Value.FocusAsync()" type="submit">Add tag</button>
Run Code Online (Sandbox Code Playgroud)

Blazor:让困难的事情变得简单,让简单的事情变得困难!

Jes*_*ood 7

FocusAsync要解释幕后发生的事情,请调用 JavaScript,但 Blazor 会在发生这种情况后重新渲染。因此,您需要FocusAsync像这样调用 OnAfterRenderAsync 方法:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await ele.Element.Value.FocusAsync();
}
Run Code Online (Sandbox Code Playgroud)

使用 JavaScript可能不是很明显FocusAsync,但这就是它不起作用的原因。有关调用 JavaScript 的文档摘录如下:

要将 JavaScript 互操作调用延迟到保证此类调用有效的时间点,请重写 OnAfterRender{Async} 生命周期事件。仅在应用程序完全呈现后才会调用此事件。

来源