Blazor Server Side, problem ze zrozumieniem kiedy UI się aktualizuje.

0

Witam,
Na początku zaznaczę, że jeśli chodzi o programowanie to jestem zielony jak wiosenna trawa. Udało mi się coś zrobić, niestety nie rozumiem zachowania i mam nadzieję, że ktoś mi wyjaśni.
Zadanie było (dla wszystkich poza mną) banalnie prostę - wyświetlić spinner w czasie gdy dane z serwera są wczytywane. Gdy to się skończy to wyłączyć spinner i pokazać dane w tabelce.

Technologia to Blazor Server Side.

<button class="btn btn-primary" @onclick="LoadData">Load Data</button>

@if (showSpinner)
{
    <div class="spinner">5</div>
}

@if (data != null)
{
    <table class="table">
        <thead>
            <tr>
                <th>DBA</th>
                <th>MerchantCountry</th>
                <th>OpenDate</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var merchant in data)
            {
                <tr>
                    <td>@merchant.DBA</td>
                    <td>@merchant.MerchantCountry</td>
                    <td>@merchant.OpenDate</td>
                    <td>@merchant.Status</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    MerchantData[] data;
    bool showSpinner = false;

    protected async void LoadData()
    {
        showSpinner = true;  
        await Task.Run(() => GetData());
        showSpinner = false;
        this.StateHasChanged();        
    }

    protected async Task GetData()
    {
        data = await MerchantService.GetMerchantDataAsync();
    }
}

W momencie jak klikam na formatkę to spinner się nie pokazuje. I to jest dość zrozumiałe, skoro stworzona property showSpinner jest na false. Następnie po kliknęciu w guzik LoadData property showSpinner zmienia się na true i wszystko się ładnie pokazuje. Więc tutaj zakładam, że ta komunikacja przebiega sama, w sensie ta property powiadomiła UI aby się odświeżyło. W następnym kroku wczytuje swoje dane z serwera, a następnie wyłączam spinner. Bez linijki this.StteHasChanged spinner się nie wyłacza pomimo, że dane się załadowały i UI się nie updatuje o tabelę. Czyli tak jaby teraz UI nie zostało poinformowane. I nie bardzo rozumem dlaczego?

Z góry dziękuję za pomoc.

0

Spróbuj

        protected async Task GetData()
        {
            data = await MerchantService.GetMerchantDataAsync();
            await InvokeAsync(StateHasChanged);
        }
0

To jest spowodowane tym że zwracasz async void zamiast async Task. Masz po prostu race condition.

Całkowicie dziwnie robisz tą asynchroniczność, ten async void i do tego wywoływanie GetData w Task.Run zamiast po prostu to awaitować. Nadrób zaległości z async/await w .Net bo to jest chyba Twoim źródłem problemu.

EDIT: trochę więcej informacji dla Ciebie

1 użytkowników online, w tym zalogowanych: 0, gości: 1