Sdílet prostřednictvím


Přehled správy stavu ASP.NET Core Blazor

Tento článek a další články v tomto uzlu popisují běžné přístupy k údržbě dat (stavu) uživatele při používání aplikace a napříč relacemi prohlížeče, včetně během předrenderování serveru.

Typickým požadavkem při Blazor vývoji aplikací je sdílení stavu mezi komponentami:

  • Nadřazený podřízený objekt: Nadřazená komponenta předává podřízené komponentě stav pomocí parametrů.
  • Podřízená komponenta nadřazená: Podřízená komponenta umožňuje datovou vazbu s jejím stavem nebo poskytuje stav prostřednictvím zpětných volání.
  • Nadřazený k potomkům: Nadřazený složek sdílí stav se všemi jeho potomky pomocí kaskádových hodnot.
  • Celé aplikace: Stav se sdílí napříč celou aplikací pomocí nakonfigurovaných stavových služeb aplikace.
  • Každý okruh: Stav se sdílí pro konkrétní okruh pomocí služeb stavu aplikace s vymezeným oborem.

Trvalý stav může vyžadovat, aby se zachovaly aktualizace stránek, obnovené okruhy a předběžné provedení. Stát často vyžaduje centrální správu, sledování a testování. Umístění a techniky pro zachování stavu jsou vysoce proměnlivé.

Blazor neposkytuje komplexní, názornou správu stavů. Produkty a služby kontejneru stavu třetích stran, které bezproblémově pracují s Blazor, jako jsou Flux, Redux a MobX, splňují prakticky všechny požadavky aplikace.

Zbývající část tohoto článku popisuje obecné strategie správy stavu pro libovolný typ Blazor aplikace.

Správa stavu pomocí adresy URL

U přechodných dat představujících stav navigace modelujte data jako součást adresy URL. Mezi příklady modelu stavu uživatele v adrese URL patří:

  • ID zobrazené entity.
  • Číslo aktuální stránky ve stránkované mřížce.

Obsah adresního řádku prohlížeče se zachová:

  • Pokud uživatel stránku znovu načte ručně.
  • Pouze scénáře na straně serveru: Pokud se webový server stane nedostupným a uživatel musí stránku znovu načíst, aby se mohl připojit k jinému serveru.

Informace o definování vzorů adres URL pomocí @page direktivy najdete v tématu ASP.NET Blazor Základní směrování a navigace.

Služba pro ukládání stavu v paměti

Vnořené komponenty obvykle svazují data pomocí zřetězené vazby, jak je popsáno v ASP.NET Core Blazor datové vazby. Vnořené a nenestované komponenty můžou sdílet přístup k datům pomocí registrovaného kontejneru stavu v paměti. Třída kontejneru vlastního stavu může použít přiřaditelné Action k oznamování změn stavu komponentám v různých částech aplikace. V následujícím příkladu:

  • Komponenty v páru používají kontejner stavu ke sledování vlastnosti.
  • Jedna komponenta v následujícím příkladu je vnořená do druhé komponenty, ale k tomu, aby tento přístup fungoval, není nutné vnoření.

Důležité

Příklad v této části ukazuje, jak vytvořit službu kontejneru stavu v paměti, zaregistrovat službu a používat ji v komponentách. Příklad neuchovává data bez dalšího vývoje. V případě trvalého úložiště dat musí kontejner stavu přijmout základní mechanismus úložiště, který přežije, když se vymaže paměť prohlížeče. Toho lze dosáhnout pomocí localStorage/sessionStorage nebo jiné technologie.

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();
}

Klientské aplikace (Program soubor):

builder.Services.AddSingleton<StateContainer>();

Serverové aplikace (Program soubor, ASP.NET Core v .NET 6 nebo novější):

builder.Services.AddScoped<StateContainer>();

Serverové aplikace (Startup.ConfigureServices z Startup.cs, obvykle v .NET 6 nebo starší):

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;
    }
}

Předchozí komponenty implementují IDisposable a OnChange delegáti se odhlásí v Dispose metodách, které jsou volány rámcovým systémem při likvidaci komponent. Další informace najdete v tématu odstranění komponenty ASP.NET Core Razor.

Kaskádové hodnoty a parametry

Pomocí kaskádových hodnot a parametrů můžete spravovat stav tokem dat z nadřazené komponenty do sestupných Razor komponent:

  • Pokud chcete využívat stav napříč mnoha komponentami.
  • Pokud existuje jen jeden objekt stavu nejvyšší úrovně, který se má zachovat.

Kaskádové hodnoty na kořenové úrovni s CascadingValueSource<TValue> umožňují komponentě Razor přijímat oznámení o změnách těchto hodnot. Další informace a funkční příklad najdete v příkladu NotifyingDalekASP.NET Core Blazor kaskádových hodnot a parametrů.

Podpora úprav stavu z vnějšího Blazorkontextu synchronizace

Pokud používáte vlastní službu správy stavu, ve které chcete podporovat úpravy stavu mimo kontext synchronizace Blazor(například z časovače nebo služby na pozadí), musí všechny komponenty, které využívají, obálit volání StateHasChanged do ComponentBase.InvokeAsync. Tím zajistíte, že se oznámení o změně zpracuje v kontextu synchronizace rendereru.

Pokud služba správy stavu nevolá StateHasChanged na Blazorkontext synchronizace, vyvolá se následující chyba:

System.InvalidOperationException: Aktuální vlákno není přidruženo k Dispatcheru. Pomocí InvokeAsync() můžete předat řízení Dispečerovi při aktivaci vykreslování nebo změně stavu součásti.

Pro více informací a příklad, jak tuto chybu vyřešit, naleznete v tématu ASP.NET Core Razor vykreslování komponent.