Blazor - отображать ожидание или спиннер при вызове API - PullRequest
1 голос
/ 14 июня 2019

В моем приложении Blazer я делаю вызов API для внутреннего сервера, который может занять некоторое время.Мне нужно отобразить обратную связь с пользователем, курсор ожидания или изображение "spinner".Как это сделать в Blazor?

Я пытался использовать CSS и включать и выключать CSS, но страница не обновляется до завершения вызова.Любые предложения будут с благодарностью.

@functions {
    UserModel userModel = new UserModel();
    Response response = new Response();
    string errorCss = "errorOff";
    string cursorCSS = "cursorSpinOff";

    protected void Submit()
    {
        //Show Sending...
        cursorCSS = "";
        this.StateHasChanged();
        response = Service.Post(userModel);
        if (response.Errors.Any())
        {
            errorCss = "errorOn";
        }
        //turn sending off
        cursorCSS = "cursorSpinOff";
        this.StateHasChanged();
    }
}

Ответы [ 2 ]

2 голосов
/ 15 июня 2019

Ниже приведено содержимое файла FetchData.razor из шаблонов Blazor

  • Обратите внимание, что файл состоит из двух частей: HTML, смешанный с C # (Razor), и код C # в @блок кода, в котором мы определяем массив объекта WeatherForecast, который называется прогнозом.Этот массив будет содержать объекты WeatherForecast, возвращенные из http-вызова, выполненного в методе OnInitAsync, на сервер.

    • Обратите внимание, что оператор if (@if (forecasts == null)) проверяет, были ли уже получены объекты WeatherForecast.Пока переменные прогнозы равны нулю, отображается HTML <p><em>Loading...</em></p>.Вы можете добавить сюда столько HTML, сколько вам нужно, включая изображения, счетчики и т. Д.

    • Как только прогнозы назначены объектам WeatherForecast, отображается таблица HTML с полученными данными

    Надеюсь, это поможет ...

 @page "/fetchdata"
 @using BlazorHosted_CSharp.Shared
 @inject HttpClient Http

 <h1>Weather forecast</h1>

 <p>This component demonstrates fetching data from the server.</p>

 @if (forecasts == null)
 {
     <p><em>Loading...</em></p>
 }
 else
 {
     <table class="table">
         <thead>
             <tr>
                 <th>Date</th>
                 <th>Temp. (C)</th>
                 <th>Temp. (F)</th>
                 <th>Summary</th>
             </tr>
         </thead>
         <tbody>
             @foreach (var forecast in forecasts)
             {
                 <tr>
                     <td>@forecast.Date.ToShortDateString()</td>
                     <td>@forecast.TemperatureC</td>
                     <td>@forecast.TemperatureF</td>
                     <td>@forecast.Summary</td>
                 </tr>
             }
         </tbody>
     </table>
 }

 @code {
     WeatherForecast[] forecasts;

     protected override async Task OnInitAsync()
     {
         forecasts = await Http.GetJsonAsync<WeatherForecast[]>("api/SampleData/WeatherForecasts");
     }
 }
1 голос
/ 20 июня 2019

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

  1. Использовать async функции.
  2. Вносить изменения в виртуальный домен.
  3. Разблокировать основной поток (Iиспользуйте await Task.Delay(1))
  4. Продолжите выполнение задачи.

Пример

async Task AsyncLongFunc()    // this is an async task
{
    spinning=true;
    await Task.Delay(1);      // changes are flushed
    LongFunc();               // usually with a wait ( is a web request)
    currentCount++;
    spinning=false;
    await Task.CompletedTask; // just to avoid non await warning.
}

Как видите, StateHasChanged - этоне нужно.

Примечание: IDK, если есть более простой или более элегантный способ сделать это.

Эффект:

enter image description here

Полный код страницы (отредактировано, совместимо с netcore3 preview6) :

@page "/counter"

<h1>Counter</h1>

<p>Current count: 
   @(spinning?"Incrementing .... (the spinning effect)":currentCount.ToString())
</p>

<button class="btn btn-primary" 
        @onclick="@IncrementCount">Click me</button>

<button class="btn  @(spinning?"btn-dark":"btn-primary") " 
        @onclick="@AsyncLongFunc">Click me Async</button>

@code {                     
    int currentCount = 0;
    bool spinning = false;
    void IncrementCount()
    {
        currentCount++;
    }

    async Task AsyncLongFunc()
    {
        spinning=true;
        await Task.Delay(1);
        LongFunc();
        currentCount++;
        spinning=false;
        await Task.CompletedTask;
    }

    void LongFunc() => Task.Delay(2000).Wait();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...