NavigateTo не сразу показывает новую страницу - PullRequest
1 голос
/ 16 июня 2020

У меня есть приложение Blazor WebAssembly со списком и страницей редактирования.

Когда я просматриваю список объектов и нажимаю на него для редактирования, с помощью компонента NavLink браузер переходит на страницу редактирования, отображая мой компонент загрузчика, пока страница не загрузится.

Это прекрасно работает.

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

private async Task OnValidSubmitAsync()
{
    this.IsBusy = true;

    var @event =
        await this.EventService.UpdateByIdAsync(
            this.Id,
            this.EventUpdateOptions);

    this.IsBusy = false;

    this.NavigationManager.NavigateTo($"/teams/{this.Event.Team.Id}/events");
}

Я ожидал, что он перейдет на страницу списка, снова отобразит мой компонент Loader, а затем отобразит страницу списка.

Но что происходит: он остается на странице редактирования до тех пор, пока страница списка не будет отображена, я никогда не вижу свой компонент загрузчика, и для пользователя он выглядит так, как будто он просто висит на странице редактирования.

Обходной путь - отобразить мой загрузчик в OnValidateSubmitAsync после того, как я закончу сохранение объекта.

Я новичок в Blazor, но жизненный цикл страницы все еще снижается, поэтому возможно, что мой подход неверный. Просто немного запутался в том, что здесь происходит, и есть ли способ заставить страницу списка отображаться с помощью загрузчика.

Надеюсь, это имело какой-то смысл. ?

1 Ответ

2 голосов
/ 16 июня 2020

Основываясь на вашем комментарии к ответу @ enet, один из возможных ответов заключается в том, что ваша страница загрузки списка никогда не прерывает logi c загрузки списка, освобождая его от потока пользовательского интерфейса, поэтому, по сути, все по-прежнему работает синхронно. Если это так, есть 2 простых способа обойти это.

Метод 1

Вы можете использовать переопределение OnInitializedAsync для загрузки списка при загрузке страницы. Важная часть состоит в том, что вам нужно сделать что-то в методе перед загрузкой вашего списка, что заставит среду выполнения построить продолжение задачи и вернуть управление потоку пользовательского интерфейса, и Task.Delay(); отлично работает. Итак, ваш метод выглядит примерно так:

protected override async Task OnInitializedAsync()
{
    // await the delay, breaks the UI thread free from following logic
    await Task.Delay(1);

    // Populate your list with a background task that you await
    // Assumes you already have the list initialized and just need values
    ListValues = await Someservice.GetListValuesAsync();

    // You may not need this call, but if so you might need to invoke it async
    // Doing so will synchronize back to the UI thread 
    await InvokeAsync(StateHasChanged);
}

Метод 2

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

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        ListValues = await Someservice.GetListValuesAsync();

        // Since you awaited the list population, now you can update UI
        MethodToSwitchUiToListView();

        // this may be needed as well
        await InvokeAsync(StateHasChanged);
    }
}

Я предпочитаю использовать метод 2 вместо метода 1, поскольку он позволяет мне создавать пользовательский интерфейс, который очень просто представлять состояние загрузки, а затем загружать несколько разделов параллельно и переключать пользовательский интерфейс по мере того, как данные становятся доступными. Во-вторых, в Blazor Server (который, похоже, не относится к вашему случаю) метод OnInitializedAsyn c вызывается дважды, но OnAfterRender вызывается только один раз. В любом случае должен работать.

Дайте мне знать, если это поможет.

PS - Метод NavigationManager.NavigateTo() также принимает необязательный второй параметр в качестве логического, чтобы принудительно загрузить страницу. Если установлено значение true, выполняется принудительная перезагрузка и обновление sh. Я рекомендую поэкспериментировать с этим, если вы еще этого не сделали, так как это может быть полезно вернуться на текущую страницу. Примером могут служить такие вещи, как сброс сложных форм, когда имеет смысл начать все сначала, а не пытаться полностью изменить состояние, и у меня было несколько разочаровывающих обстоятельств, которые были решены с помощью этого простого второго параметра. Этот может также помочь в вашем случае.

...