Обновление вручную указанных элементов c html в блейзоре - PullRequest
1 голос
/ 20 апреля 2020

Я изучаю Blazor, создавая веб-приложение на стороне клиента.

Я сделал al oop, который увеличивает число каждые 10 мс, и, вызывая StateHasChanged, мой компонент перерисовывается каждые l oop. У меня также есть индикатор выполнения, но я хочу перерисовывать его каждую секунду только для увеличения производительности.

Могу ли я это сделать? Или я поступаю неправильно?

Примеры кода для контекста:

    <div>
        <span>Count = @Count / @Max</span>
        <br />
        <span>Percent = @Percent</span>
        <div class="progress">
            <div class="progress-bar" role="progressbar" style="width: @Percent%"></div>
        </div>
    </div>

@code {

    public int Max { get; set; } = 500;
    public int Count { get; set; }
    public int Percent => (int)(100 * (double)Count / (double)Max);
    public bool IsRunning { get; protected set; }

    protected override Task OnInitializedAsync()
    {
        Task.Run(() => Loop());
        return base.OnInitializedAsync();
    }

    public async Task Loop()
    {
        if (IsRunning) return;
        IsRunning = true;

        while (IsRunning && Count < Max)
        {
            Count++;
            StateHasChanged();

            // ~every second
            if (Count % 100 == 0)
            {
                // re-render the progress bar
            }
            await Task.Delay(10); // ~loop duration in ms
        }
    }
}

1 Ответ

1 голос
/ 21 апреля 2020

Вы были ОЧЕНЬ близко, просто нужно немного переставить ваш метод OnInitializedAsync и переместить ваши проценты logi c в l oop. Обратите внимание, что OnInitializedAsync теперь помечен async, поэтому вы можете дождаться выполнения функции l oop вместо запуска задания Я показываю только те элементы, которые ниже менялись.

public int Percent { get; set; }

protected override async Task OnInitializedAsync()
{
    await Loop();
    // Don't need a call to base here, 
    // in base it's just a stub to satisfy 
    // the original call from the Blazor framework. 
}

public async Task Loop()
{
    if (IsRunning)
        return;
    IsRunning = true;
    while (IsRunning && Count < Max)
    {
        Count++;
        // ~every second
        if (Count % 100 == 0)
        {
            Percent = (int)(100 * (double)Count / (double)Max);
        }
        StateHasChanged();
        await Task.Delay(10); // ~loop duration in ms
    }

    IsRunning = False;
}

Поскольку Loop является ожидаемым заданием, оно будет выполнено, но остальная часть DOM будет отображаться, а затем каждый раз, когда он нажимает StateHasChanged(), будет повторяться. Поскольку приведение к проценту cal c теперь выполняется в l oop и выполняется только с интервалами, оно немного дешевле при приведении, но DOM по-прежнему обновляется каждый раз. Blazor спроектирован так, чтобы DOM отличался как можно меньшим, чтобы вам вообще не пришлось наносить удары.

Я запустил это в новом приложении Blazor Server с упомянутыми изменениями, и это сработало как шарм.

...