Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье и других статьях в этом узле описываются распространенные подходы к поддержанию данных пользователя (состояния) во время использования приложения и между сеансами браузера, в том числе во время предварительной подготовки сервера.
Типичным требованием во время Blazor разработки приложений является общий доступ к состоянию между компонентами:
- Родительский элемент дочерним: родительский компонент передает состояние дочернему компоненту с помощью параметров.
- Дочерний к родителю: дочерний компонент включает привязку данных к его состоянию или предоставляет состояние через обратные вызовы.
- Родительский для потомков: родительское состояние совместно с всеми потомками с использованием каскадных значений.
- На уровне приложения: состояние совместно используется для всего приложения с помощью настроенных служб состояний приложений.
- На канал: для определенного канала используется состояние с использованием служб состояний приложений с областью действия.
Сохраняемое состояние может потребоваться для выживания обновлений страниц, возобновления каналов и предварительной подготовки. Для состояния часто требуется централизованное управление, отслеживание и тестирование. Расположения и методы сохранения состояния являются высокой переменной.
Blazor не обеспечивает комплексное, с точки зрения управления состояниями. Сторонние продукты и службы контейнера состояния, которые легко работают с Blazorтакими продуктами, как Flux, Redux и MobX, удовлетворяют практически любому требованию приложения.
Оставшаяся часть этой статьи описывает общие стратегии управления состоянием для любого типа Blazor приложения.
Управление состоянием с помощью URL-адреса
Для временных данных, представляющих состояние навигации, моделируют данные как часть URL-адреса. Ниже приведены примеры данных о состоянии пользователя, которые моделируются в URL-адресе.
- Идентификатор просматриваемой сущности.
- Номер текущей страницы в сетке, разбитой на страницы.
Содержимое адресной строки браузера будет сохраняться в следующих случаях.
- Если пользователь вручную обновляет страницу.
- Только в сценариях на стороне сервера: если веб-сервер становится недоступным, и пользователь вынужден перезагрузить страницу, чтобы подключиться к другому серверу.
Сведения о том, как определить шаблоны URL-адресов с помощью директивы @page, см. в разделе ASP.NET Core МаршрутизацияBlazor.
Служба контейнера данных в оперативной памяти
Вложенные компоненты обычно привязываются к данным с помощью цепочки привязки, как описано в статье Привязка к данным в ASP.NET Core Blazor. Вложенные и невложенные компоненты могут иметь общий доступ к данным с помощью зарегистрированного контейнера состояния в памяти. Пользовательский класс контейнера состояния может использовать назначаемый Action, чтобы уведомлять компоненты в других частях приложения об изменениях состояния. В следующем примере :
- Пара компонентов использует контейнер состояния для отслеживания свойства.
- Один из компонентов в следующем примере вложен в другой компонент, но для использования этого подхода вложение не требуется.
Это важно
В этом разделе показано, как создать службу контейнера состояния в памяти, зарегистрировать службу и использовать службу в компонентах. Пример не сохраняет данные без дальнейшей доработки. Для постоянного хранения данных контейнер состояния должен принять базовый механизм хранения, который сохраняется при очистке памяти браузера. Это можно сделать с помощью localStorage/sessionStorage или другой технологии.
StateContainer.cs:
public class StateContainer
{
private string? savedString;
public string Property
{
get => savedString ?? string.Empty;
set
{
savedString = value;
NotifyStateChanged();
}
}
public event Action? OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
Клиентские приложения (Program файл):
builder.Services.AddSingleton<StateContainer>();
Серверные приложения (Program файл, ASP.NET Core в .NET 6 или более поздней версии):
builder.Services.AddScoped<StateContainer>();
Серверные приложения (Startup.ConfigureServices обычно в .NET 6 или более ранних версиях Startup.cs):
services.AddScoped<StateContainer>();
Shared/Nested.razor:
@implements IDisposable
@inject StateContainer StateContainer
<h2>Nested component</h2>
<p>Nested component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the Nested component
</button>
</p>
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property =
$"New value set in the Nested component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
StateContainerExample.razor:
@page "/state-container-example"
@implements IDisposable
@inject StateContainer StateContainer
<h1>State Container Example component</h1>
<p>State Container component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the State Container Example component
</button>
</p>
<Nested />
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property = "New value set in the State " +
$"Container Example component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
Предыдущие компоненты реализуют IDisposable, а делегаты OnChange отписываются в методах Dispose, которые вызываются фреймворком при удалении компонентов. Дополнительные сведения см. в разделе ASP.NET Core Razor утилизации компонентов.
Каскадные значения и параметры
Используйте каскадные значения и параметры для управления состоянием путем потоков данных из компонента предка Razor в компоненты потомков:
- Для потребления состояния во множестве компонентов.
- Если имеется только один объект состояния верхнего уровня для сохранения.
Каскадные значения корневого уровня с CascadingValueSource<TValue> разрешают Razor уведомления подписчика компонента об измененных каскадных значениях. Дополнительные сведения и рабочий пример см. в примере NotifyingDalekASP.NET Core Blazor каскадных значений и параметров.
Поддержка изменений состояния извне Blazorконтекста синхронизации
При использовании пользовательской службы управления состояниями, в которой требуется поддерживать изменения состояния вне контекста синхронизации Blazor(например, из таймера или фоновой службы), все используемые компоненты должны упаковать вызов StateHasChanged в ComponentBase.InvokeAsync. Это гарантирует, что уведомление об изменении обрабатывается в контексте синхронизации отрисовщика.
Если служба управления состоянием не вызывает StateHasChanged в контексте синхронизации объекта Blazor, возникает следующая ошибка:
System.InvalidOperationException: 'Текущий поток не связан с диспетчером. Используйте InvokeAsync(), чтобы переключить выполнение на Dispatcher при активации рендеринга или состояния компонента.
Дополнительные сведения и пример устранения этой ошибки см. в статье
ASP.NET Core