Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo e gli altri articoli di questo nodo descrivono approcci comuni per la gestione dei dati (stato) di un utente durante l'uso di un'app e tra le sessioni del browser, incluso durante la pre-gestione dei server.
Un requisito tipico durante Blazor lo sviluppo di app è la condivisione dello stato tra i componenti:
- Padre a figlio: un componente padre passa lo stato a un componente figlio usando i parametri.
- Da figlio a padre: un componente figlio consente il data binding allo stato o fornisce lo stato tramite callback.
- Padre ai discendenti: un genitore condivide lo stato con tutti i suoi discendenti utilizzando valori a cascata.
- A livello di app: lo stato viene condiviso nell'intera app usando i servizi di stato dell'app configurati.
- Per circuito: lo stato viene condiviso per un circuito specifico usando i servizi di stato dell'app con ambito.
Potrebbe essere necessario che lo stato persistente resista agli aggiornamenti delle pagine, al ripristino dei circuiti e al prerendering. Lo stato richiede spesso la gestione centrale, il rilevamento e il test. Le posizioni e le tecniche per la persistenza dello stato sono altamente variabili.
Blazor non fornisce una gestione dello stato completa e opinata. I prodotti e i servizi contenitore di stato di terze parti che funzionano perfettamente con Blazor, ad esempio Flux, Redux e MobX, soddisfano praticamente qualsiasi requisito dell'app.
Nella parte restante di questo articolo vengono illustrate le strategie generali di gestione dello stato per qualsiasi tipo di Blazor app.
Gestione dello stato tramite l'URL
Per i dati temporanei che rappresentano lo stato di navigazione, modellare i dati come parte dell'URL. Esempi di stato utente modellati nell'URL includono:
- ID di un'entità visualizzata.
- Numero di pagina corrente in una griglia paginata.
Il contenuto della barra degli indirizzi del browser viene conservato:
- Se l'utente ricarica manualmente la pagina.
- Solo scenari lato server: se il server Web diventa non disponibile, e l'utente è costretto a ricaricare la pagina per connettersi a un server diverso.
Per informazioni sulla definizione dei pattern di URL con la @page direttiva, vedere ASP.NET Core Blazor routing e navigazione.
Servizio contenitore di stato in memoria
I componenti annidati in genere associano i dati usando il bind concatenato come descritto in ASP.NET Core Blazor data binding. I componenti annidati e non registrati possono condividere l'accesso ai dati usando un contenitore di stato in memoria registrato. Una classe contenitore di stato personalizzata può usare un oggetto assegnabile Action per notificare ai componenti in parti diverse dell'app modifiche di stato. Nell'esempio seguente:
- Una coppia di componenti usa un contenitore di stato per tenere traccia di una proprietà.
- Un componente nell'esempio seguente è annidato nell'altro componente, ma l'annidamento non è necessario per il funzionamento di questo approccio.
Importante
Nell'esempio riportato in questa sezione viene illustrato come creare un servizio contenitore di stato in memoria, registrare il servizio e usare il servizio nei componenti. L'esempio non rende persistenti i dati senza ulteriore sviluppo. Per l'archiviazione permanente dei dati, il contenitore di stato deve adottare un meccanismo di archiviazione sottostante che sopravvive quando la memoria del browser viene cancellata. Questa operazione può essere eseguita con localStorage/sessionStorage o con altre tecnologie.
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();
}
Applicazioni lato client (Program file)
builder.Services.AddSingleton<StateContainer>();
App sul lato server (Program file, ASP.NET Core in .NET 6 o versione successiva):
builder.Services.AddScoped<StateContainer>();
App lato server (Startup.ConfigureServices di Startup.cs, in genere in .NET 6 o versioni precedenti):
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;
}
}
I componenti precedenti implementano IDisposable, e le sottoscrizioni ai delegati OnChange vengono annullate nei metodi Dispose, chiamati dal framework quando i componenti vengono eliminati. Per ulteriori informazioni, vedere eliminazione dei componenti di ASP.NET Core Razor.
Valori e parametri a cascata
Usare i valori e i parametri a catena per gestire lo stato eseguendo il flusso dei dati da un componente predecessore Razor ai componenti discendenti:
- Per utilizzare lo stato in molti componenti.
- Se è presente un solo oggetto di stato di primo livello da rendere persistente.
I valori a cascata a livello radice con un CascadingValueSource<TValue> consentono al componente sottoscrittore di Razor notifiche sui valori a cascata modificati. Per altre informazioni e un esempio funzionante, vedere l'esempio di NotifyingDalek in ASP.NET Core Blazor valori e parametri a cascata.
Supportare le modifiche dello stato da fuori del contesto di sincronizzazione di Blazor
Quando si utilizza un servizio di gestione dello stato personalizzato in cui si desidera supportare le modifiche dello stato dall'esterno del contesto di sincronizzazione di Blazor(ad esempio da un timer o da un servizio in background), tutti i componenti consumatori devono racchiudere la chiamata StateHasChanged in ComponentBase.InvokeAsync. In questo modo, la notifica delle modifiche viene gestita nel contesto di sincronizzazione del renderer.
Quando il servizio di gestione dello stato non chiama StateHasChanged sul contesto di sincronizzazione di Blazor, viene generato l'errore seguente:
System.InvalidOperationException: 'Il thread corrente non è associato al Dispatcher. Usare InvokeAsync() per trasferire l'esecuzione al Dispatcher quando si attiva il rendering o lo stato del componente.
Per ulteriori informazioni e un esempio di come risolvere questo errore, consultare ASP.NET Core Razor component rendering.