Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel und den anderen Artikeln in diesem Knoten werden allgemeine Ansätze für die Aufrechterhaltung der Daten (Status) eines Benutzers beschrieben, während sie eine App und browserübergreifende Sitzungen verwenden, einschließlich während der Servervorrenderung.
Eine typische Anforderung während der Blazor App-Entwicklung ist das Teilen des Zustands zwischen Komponenten.
- Übergeordnetes Element zu untergeordnetem Element: Eine übergeordnete Komponente übergibt den Zustand mithilfe von Parametern an eine untergeordnete Komponente.
- Untergeordnetes Element zum übergeordneten Element: Eine untergeordnete Komponente ermöglicht die Datenbindung an ihren Zustand oder stellt status über Rückrufe bereit.
- Elter zu Nachkommen: Ein Elter teilt den Zustand mit allen seinen Nachkommen unter Verwendung kaskadierender Werte.
- App-weit: Der Status wird über die gesamte App mit konfigurierten App-Zustandsdiensten geteilt.
- Pro Schaltkreis: Der Zustand wird für einen bestimmten Schaltkreis mittels bereichsbezogener App-Statusdienste geteilt.
Der beibehaltene Zustand muss möglicherweise Seitenaktualisierungen, fortgesetzte Sitzungen und das Vorrendering überdauern. Der Staat erfordert häufig eine zentrale Verwaltung, Nachverfolgung und Testen. Die Speicherorte und Techniken für den permanenten Zustand sind sehr variabel.
Blazor bietet keine umfassende, meinungsstarke Zustandsverwaltung. Drittanbieter-Containerprodukte und -dienste, die nahtlos mit BlazorFlux, Redux und MobX zusammenarbeiten, erfüllen nahezu jede App-Anforderung.
Im restlichen Teil dieses Artikels werden allgemeine Zustandsverwaltungsstrategien für jede Art von Blazor App erläutert.
Zustandsverwaltung mit der URL
Modellieren Sie vorübergehende Daten, die den Navigationszustand darstellen, als Teil der URL. Beispiele für in der URL modellierte Benutzerzustände:
- Die ID einer angezeigten Entität.
- Die aktuelle Seitenzahl in einem ausgelagerten Raster.
Der Inhalt der Adressleiste des Browsers wird in folgenden Fällen beibehalten:
- Der Benutzer lädt die Seite nochmals manuell.
- Nur serverseitige Szenarien: Wenn der Webserver nicht verfügbar ist und der Benutzer gezwungen ist, die Seite neu zu laden, um eine Verbindung mit einem anderen Server herzustellen.
Informationen zum Definieren von URL-Mustern mit der @page Direktive finden Sie unter ASP.NET Core Blazor Routing.
Arbeitsspeicherinterner Zustandscontainer des Diensts
Geschachtelte Komponenten binden Daten in der Regel mithilfe verketteter Bindungen, wie in Blazor-Datenbindung in ASP.NET Core beschrieben. Geschachtelte und nicht geschachtelte Komponenten können den Zugriff auf Daten über einen registrierten arbeitsspeicherinternen Zustandscontainer teilen. Eine benutzerdefinierte Zustandscontainerklasse kann eine Action zuweisen, um Komponenten in verschiedenen Teilen der App über Zustandsänderungen zu informieren. Im folgenden Beispiel:
- Ein Komponentenpaar verwendet einen Zustandscontainer, um eine Eigenschaft nachzuverfolgen.
- Eine Komponente im folgenden Beispiel ist in der anderen Komponente geschachtelt, aber Schachtelung ist nicht erforderlich, damit dieser Ansatz funktioniert.
Von Bedeutung
Das Beispiel in diesem Abschnitt veranschaulicht, wie Sie einen In-Memory-Containerdienst erstellen, den Dienst registrieren und den Dienst in Komponenten verwenden. Das Beispiel speichert keine Daten ohne weitere Entwicklung. Für die dauerhafte Speicherung von Daten muss der Statuscontainer einen zugrunde liegenden Speichermechanismus übernehmen, der weiterhin besteht, wenn der Browserspeicher gelöscht wird. Dies kann mit localStorage/sessionStorage oder einer anderen Technologie erreicht werden.
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();
}
Clientseitige Apps (Program Datei):
builder.Services.AddSingleton<StateContainer>();
Serverseitige Apps (Program Datei, ASP.NET Core in .NET 6 oder höher):
builder.Services.AddScoped<StateContainer>();
Serverseitige Apps (Startup.ConfigureServices von Startup.cs, in der Regel in .NET 6 oder früher):
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;
}
}
Die vorangehenden Komponenten implementieren IDisposable, und die OnChange-Delegaten werden in den Dispose-Methoden abbestellt, die vom Framework aufgerufen werden, wenn die Komponenten verworfen werden. Weitere Informationen finden Sie unter ASP.NET Core Razor Komponentenentsorgung.
Kaskadierende Werte und Parameter
Verwenden Sie kaskadierende Werte und Parameter, um den Zustand zu verwalten, indem Sie Daten von einer vorgänger Razor Komponente zu untergeordneten Komponenten fließen lassen:
- Um den Zustand über viele Komponenten hinweg zu nutzen.
- Es muss nur ein Zustandsobjekt auf der obersten Ebene beibehalten werden.
Kaskadierende Werte auf Stammebene mit einem CascadingValueSource<TValue> ermöglichen Razor-Komponenten, Benachrichtigungen über geänderte kaskadierende Werte zu erhalten. Weitere Informationen und ein funktionierendes Beispiel finden Sie im NotifyingDalek Beispiel in ASP.NET Core Blazor kaskadierende Werte und Parameter.
Unterstützung von Statusänderungen außerhalb des Synchronisierungskontexts von Blazor
Wenn Sie einen benutzerdefinierten Zustandsverwaltungsdienst verwenden möchten, mit dem Sie Zustandsänderungen von außerhalb des Blazor Synchronisierungskontexts unterstützen können (z. B. von einem Timer oder einem Hintergrunddienst), müssen alle verbrauchenden Komponenten den StateHasChanged Aufruf in ComponentBase.InvokeAsync einschließen. Dadurch wird sichergestellt, dass die Änderungsbenachrichtigung im Synchronisierungskontext des Renderers behandelt wird.
Wenn der Zustandsverwaltungsdienst StateHasChanged nicht über den Synchronisierungskontext von Blazor aufruft, wird der folgende Fehler ausgelöst:
System.InvalidOperationException: „Der aktuelle Thread ist nicht dem Dispatcher zugeordnet. Verwenden Sie InvokeAsync() zum Wechseln der Ausführung auf den Dispatcher beim Auslösen des Renderings oder des Komponentenzustands.“
Weitere Informationen und ein Beispiel für die Behebung dieses Fehlers finden Sie unter ASP.NET Core Razor Komponentenrendering.