Стив Сандерсон подробно рассказывает о том, как сохранить состояние.
Для сервера на стороне сервера вам потребуется использовать любую реализацию хранилища в JavaScript, которая может быть файлами cookie, параметрами запроса илиНапример, вы можете использовать локальное / сессионное хранилище .
. В настоящее время пакеты NuGet реализуют это через IJSRuntime
, например BlazorStorage или Microsoft.AspNetCore.ProtectedBrowserStorage
Сейчасхитрость заключается в том, что серверный блейзор выполняет предварительный рендеринг страниц, поэтому код представления Razor будет выполняться и выполняться на сервере еще до его отображения в браузере клиента.Это вызывает проблему, когда IJSRuntime
и, следовательно, localStorage
недоступны в настоящее время. Вам нужно будет либо отключить предварительный рендеринг, либо дождаться отправки страницы, сгенерированной сервером, в браузер клиента и установить соединение обратно с сервером
Во время предварительного рендеринга нетинтерактивное соединение с браузером пользователя, и у браузера еще нет страниц, на которых он может запускать JavaScript.Поэтому невозможно взаимодействовать с localStorage или sessionStorage в то время.Если вы попытаетесь, вы получите ошибку, похожую на то, что вызовы взаимодействия JavaScript не могут быть выполнены в это время.Это связано с тем, что компонент выполняется предварительная визуализация.
Чтобы отключить предварительную визуализацию:
(...) откройте файл _Host.razor
и удалите вызов Html.RenderComponentAsync
.Затем откройте файл Startup.cs
и замените вызов endpoints.MapBlazorHub()
на endpoints.MapBlazorHub<App>("app")
, где App
- это тип вашего корневого компонента, а «app» - селектор CSS, указывающий, где в документе должен находиться корневой компонент.быть помещенным.
Когда вы хотите продолжить предварительную визуализацию:
@inject YourJSStorageProvider storageProvider
bool isWaitingForConnection;
protected override async Task OnInitAsync()
{
if (ComponentContext.IsConnected)
{
// Looks like we're not prerendering, so we can immediately load
// the data from browser storage
string mySessionValue = storageProvider.GetKey("x-my-session-key");
}
else
{
// We are prerendering, so have to defer the load operation until later
isWaitingForConnection = true;
}
}
protected override async Task OnAfterRenderAsync()
{
// By this stage we know the client has connected back to the server, and
// browser services are available. So if we didn't load the data earlier,
// we should do so now, then trigger a new render.
if (isWaitingForConnection)
{
isWaitingForConnection = false;
//load session data now
string mySessionValue = storageProvider.GetKey("x-my-session-key");
StateHasChanged();
}
}
Теперь к фактическому ответу, где вы хотите сохранить состояние между страницами, вы должны использовать CascadingParameter
.Крис Сэйнти объясняет это как
Каскадные значения и параметры - это способ передачи значения от компонента всем его потомкам без использования традиционных параметров компонента.
Это будет параметр, который будет классом, который содержит все ваши данные о состоянии и предоставляет методы, которые можно загружать / сохранять через поставщика хранилища по вашему выбору.Это объясняется в блоге Криса Сэйнти , в заметке Стива Сандерсона или в документах Microsoft
Обновление: Microsoft опубликовала новые документы, объясняющие Blazor'sуправление состоянием
Обновление 2: обратите внимание, что в настоящее время BlazorStorage работает неправильно для серверной версии Blazor с последним предварительным просмотром .NET SDK.Вы можете следить за этой проблемой , где я разместил временное решение