Установка фокуса на элементе Блейзора

#blazor

Вопрос:

Я использую серверную версию Blazor, и в следующем примере у меня есть эта ошибка:

«В настоящее время вызовы взаимодействия JavaScript не могут быть выполнены. Это связано с тем, что компонент статически визуализируется. Если включена предварительная настройка, вызовы взаимодействия JavaScript могут выполняться только во время метода жизненного цикла OnAfterRenderAsync.»

 File .razor:
      <RadzenTabs SelectedIndex="0" Change=@(args => OnChangeRadzenTab(args))>

File.cs:
        async void OnChangeRadzenTab(int value)
        {
            switch (value)
            {
               case 0:
                   await jsRuntime.InvokeVoidAsync("eval", $@"document.getElementById(""NameOfField"").focus()");
                   break;
               
 

Но в следующем, вместо этого, выполняется код. Почему существуют эти различия в поведении?

 File .razor:
        <RadzenMask Mask="**/**/****" Pattern="[^0-9]" Name="EndDate" Id="EndDate"
                    @bind-Value=@EndDate  @onfocusout=@(args => OnFocusOutEndDate(args)) /> 

File.cs:
        async void OnFocusOutEndDate(FocusEventArgs? value)
        {
            if (!LibB.CheckDate(EndDate))
            {
                await jsRuntime.InvokeVoidAsync("eval", $@"document.getElementById(""EndDate"").focus()");
                Error = true;
            }
        }   
 

Ответ №1:

Я предполагаю, что вы поместили первое в @if @foreach блок или, а второе-не в условный блок. Либо это, либо первый элемент управления Radzen создает подконтрольные элементы таким образом, и они вызывают обратный вызов события во время рендеринга.

В любом случае, мое решение этой проблемы состоит в том, чтобы соответствовать сообщению об ошибке и отложить JavaScript:

 bool NeedFocusChange;
async Task OnFocusOutEndDate(FocusEventArgs? value) 
{
    if (!LibB.CheckDate(EndDate))
        NeedFocusChange = true;
} 
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (NeedFocusChange)
    {
        await jsRuntime.InvokeVoidAsync("eval", $@"document.getElementById(""EndDate"").focus()");
        Error = true;
        NeedFocusChange = false;
     }
}
 

Я не знаю, что такое RadzenControls, но если вы можете получить @ref для компонента «Дата окончания», вы можете использовать новый (.net 5) FocusAsync , но он все еще использует JavaScript под капотом, я думаю:

https://www.youtube.com/watch?v=lLypM7oBwyA