Blazor EditForm теряет фокус на привязке данных

#javascript #blazor #blazor-jsinterop

#javascript #blazor #blazor-jsinterop

Вопрос:

У меня есть требование загружать новые данные в мою форму, когда пользователь нажимает стрелку вверх или вниз. И ожидается, что любая ячейка, имеющая фокус, сохраняет фокус после загрузки новых данных.

Следующий код может перехватывать ввод с клавиатуры и загружать правильную запись в мою форму, используя привязку данных. Однако я нахожу, что форма теряет фокус, как только привязываются новые данные.

MyComponent.razor:

 <span @onkeypress="@KeyHandler" @onkeydown="@KeyHandler">
    <EditForm Model="@CurrentRecord">
        <DataAnnotationsValidator />
        <ValidationSummary />
        @Content
    </EditForm>
</span>

@code {
[Parameter]
public RenderFragment Content { get; set; }
public List<MyModel> Data { get; set; } = new List<MyModel>();
private int currentIndex;

protected async Task KeyHandler(KeyboardEventArgs e)
{
    if (e.Key == "DownArrow") await LoadNextRecord();
}

async Task LoadNextRecord()
{
    CurrentRecord = Data.ElementAt(  currentIndex);
    // Form loses focus here!!
}
}
  

Теперь я могу реализовать простой javascript для фокусировки первого элемента при повторной привязке данных. Но мое требование — сохранить фокус там, где он есть. Я не смог найти общий способ получить сфокусированный элемент, а затем переориентировать без необходимости назначать идентификатор или @ref для каждого элемента в моей форме.

Есть ли другой способ решить эту проблему?

Комментарии:

1. Когда вы говорите «форма теряет фокус, как только привязываются новые данные», вы имеете в виду, что ввод теряет фокус, верно?

2. Согласно моему приведенному выше коду, когда я устанавливаю CurrentRecord, форма повторно отображается. Когда это происходит, мой ввод теряет фокус. Я хочу сохранить фокус там, где он есть (или вернуть фокус в ту же ячейку) Например, AfterRenderAsync

3. Не уверен, почему это происходит, но я думаю, что это происходит потому, что вы используете RenderFragment , попробуйте передать форму непосредственно внутрь MyComponent . Вероятно, это сработает

4. Я попытался поместить содержимое формы непосредственно в MyComponent (и прокомментировать @Content). Поведение такое же. При повторном рендеринге формы фокус пропадает.

5. Попробуйте не изменять CurrentRecord напрямую, а только его свойства. AutoMapper был бы полезен в этом случае. Я думаю, что он теряет фокус, потому что меняет ссылку на CurrentRecord , но если вы измените только значения свойств, возможно, этого не произойдет.

Ответ №1:

Есть ли другой способ решить эту проблему?

Нет, это не так… Общего способа сделать это не существует, ни прямо сейчас, ни, вероятно, в ближайшем будущем.

В настоящее время, самое большее, вы можете установить фокус ввода в Blazor следующим образом:

 <button @onclick="() => textInput.FocusAsync()">Set focus</button>
<input @ref="textInput"/>
  

Обратите внимание, что приведенный выше фрагмент кода работает в Asp.Net Только ядро 5.0 (предварительный просмотр).

Единственное решение, которое я могу предложить, — это разработать способ определить, какой элемент ввода был в фокусе последним, а затем перенаправить его с методов OnAfterRender / Async. Вам придется применить директиву @ref к каждому из ваших входных элементов или атрибуту id. Другого способа сделать это нет.

Комментарии:

1. Привет, Энет, спасибо за разъяснение параметров. Я также проверю API предварительного просмотра, который вы рекомендовали.