Обновление кнопки Blazor Server во время ожидания

У меня есть кнопка, подобная приведенной ниже на странице компонента сервера бритвы. Цель состоит в том, чтобы при нажатии кнопки она переходила в отключенный режим до тех пор, пока задача не будет завершена. Это работает на одной из страниц, но мне не удается заставить его работать на других страницах в том же приложении. Кнопка запускает функцию DoSearch() и обновляет содержимое по завершении, но не обновляет себя на полпути. Любые идеи, почему, пожалуйста?


<button type = "button" class = "btn btn-primary" @onclick = "DoSearch" disabled = "@SearchDisabled">@SearchBtnName</button>

        protected bool SearchDisabled { get; set; } = false;
        protected string SearchBtnName { get; set; } = "Search";

        protected async Task DoSearch()
        {
            SearchDisabled = true;
            SearchBtnName = "Searching ...";
            List<string> log = new();

            try
            {
                //Do some work which takes a few seconds ....
            }
            finally
            {
                SearchDisabled = false;
                SearchBtnName = "Search";
            }

        }

Я попытался изменить способ кодирования onclick, например: @onclick="@(async() => ждите DoSearch())"

Я попытался вызвать StateHasChanged() и await InvokeAsync(StateHasChanged); Я также пытался посмотреть, что еще может отличаться на этой странице, но не смог понять.

Можете показать, что у вас внутри блока try. Ваш код работает нормально: blazorfiddle.com/s/7voq7qi4

Vivendi 14.04.2023 12:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
1
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код будет работать, только если выполнить некоторую работу. Если это блок синхронного кода, завернутый в Task, то у рендерера не будет времени на обновление пользовательского интерфейса до тех пор, пока не будет завершена какая-то работа, и вы не вернете поля статуса в состояние завершения.

Чтобы процитировать ответ на аналогичный вопрос сегодня:

Вызов StateHasChanged не отображает компонент. Он ставит RenderFragment компонента в очередь Renderer. Эта очередь обслуживается [рендерером и визуализируемым компонентом] только тогда, когда рендерер получает время для запуска потока.

В приведенном ниже коде я ввел yield после обновления полей состояния, чтобы убедиться, что пользовательский интерфейс обновляется в этот момент.

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

<div class = "m-2 p-2">
    <button type = "button" class = "btn btn-primary" @onclick = "DoSearch" disabled = "@SearchDisabled">@this.SearchBtnName</button>
</div>

@code {
    protected bool SearchDisabled = false;
    protected string SearchBtnName = "Search";

    private async Task DoSearch()
    {
        SearchDisabled = true;
        SearchBtnName = "Searching ...";

        // make sure we yield to update the UI
        // Do work may be a block of synchronous wrapped in a Task!
        // Some people will suggest you do await Task.Delay(1) here Take your choice
        await Task.Yield();
        //await Task.Delay(1);

        await this.DoWork();

        SearchDisabled = false;
        SearchBtnName = "Search";
    }

    private async Task DoWork()
    {
        // emulate real async work
        await Task.Delay(2000);
    }
}

Большое спасибо! Это сработало.

user21641787 14.04.2023 12:47
Delay(1) рулит, Yield() разочаровывает.
H H 14.04.2023 12:56

@HH - ;-) - Я знал, что ты поднимешься до этого. Я почти квалифицировал некоторых людей в комментарии к коду!

MrC aka Shaun Curtis 14.04.2023 13:06

Другие вопросы по теме