Freigeben von Daten in Blazor-Anwendungen
- 7 Minuten
Blazor umfasst mehrere Möglichkeiten, Informationen zwischen Komponenten zu teilen. Sie können Komponentenparameter oder kaskadierende Parameter verwenden, um Werte von einer übergeordneten Komponente an eine untergeordnete Komponente zu senden. Das AppState-Muster ist ein weiterer Ansatz, mit dem Sie Werte speichern und von einer beliebigen Komponente in der Anwendung darauf zugreifen können.
Angenommen, Sie arbeiten an der neuen Pizzazustellungswebsite. Mehrere Pizzas sollten auf der Startseite auf die gleiche Weise angezeigt werden. Sie möchten die Pizzen anzeigen, indem Sie für jede Pizza eine untergeordnete Komponente rendern. Es sollte eine ID an diese untergeordnete Komponente übergeben werden, die bestimmt, welche Pizza angezeigt wird. Sie möchten auch einen Wert auf mehreren Komponenten speichern und anzeigen, die die Gesamtzahl der Pizzas anzeigen, die Sie heute verkauft haben.
In dieser Lektion lernen Sie drei verschiedene Techniken kennen, mit denen Sie Werte zwischen zwei oder mehr Blazor-Komponenten teilen können.
Freigeben von Informationen an andere Komponenten mithilfe von Komponentenparametern
In einer Blazor-Web-App rendert jede Komponente einen Teil von HTML. Einige Komponenten rendern eine vollständige Seite, andere rendern jedoch kleinere Markupfragmente, z. B. eine Tabelle, ein Formular oder ein einzelnes Steuerelement. Wenn Ihre Komponente nur einen Markupabschnitt rendert, müssen Sie sie als untergeordnete Komponente innerhalb einer übergeordneten Komponente verwenden. Ihre untergeordnete Komponente kann auch eine übergeordnete Komponente für andere kleinere Komponenten sein, die darin gerendert werden. Untergeordnete Komponenten werden auch als geschachtelte Komponenten bezeichnet.
In dieser Hierarchie von übergeordneten und untergeordneten Komponenten können Sie mithilfe von Komponentenparametern Informationen für alle Komponenten gemeinsam nutzen. Definieren Sie diese Parameter für untergeordnete Komponenten, und legen Sie dann deren Werte in der übergeordneten Komponente fest. Wenn Sie beispielsweise über eine untergeordnete Komponente verfügen, die Pizzafotos anzeigt, können Sie einen Komponentenparameter verwenden, um die Pizza-ID zu übergeben. Die untergeordnete Komponente sucht die Pizza anhand der ID und ruft Bilder und andere Daten ab. Wenn Sie viele verschiedene Pizzas anzeigen möchten, können Sie diese untergeordnete Komponente mehrmals auf derselben übergeordneten Seite verwenden und für jede untergeordnete Komponente eine andere ID übergeben.
Definieren Sie zunächst den Komponentenparameter in der untergeordneten Komponente. Sie definieren sie als öffentliche C#-Eigenschaft und versehen sie mit dem [Parameter] Attribut:
<h2>New Pizza: @PizzaName</h2>
<p>@PizzaDescription</p>
@code {
[Parameter]
public string PizzaName { get; set; }
[Parameter]
public string PizzaDescription { get; set; } = "The best pizza you've ever tasted."
}
Da die Komponentenparameter Mitglieder der untergeordneten Komponente sind, können Sie sie im HTML-Code mithilfe des reservierten @-Symbols von Blazor, gefolgt von ihrem Namen, rendern. Außerdem gibt der vorangehende Code einen Standardwert für den PizzaDescription Parameter an. Dieser Wert wird gerendert, wenn die übergeordnete Komponente keinen Wert übergibt. Andernfalls überschreibt der von der übergeordneten Komponente übergebene Wert ihn.
Sie können auch benutzerdefinierte Klassen in Ihrem Projekt als Komponentenparameter verwenden. Sehen Sie sich diese Klasse an, die einen Belag beschreibt:
public class PizzaTopping
{
public string Name { get; set; }
public string Ingredients { get; set; }
}
Sie können dies als Komponentenparameter auf die gleiche Weise wie ein Parameterwert verwenden, um auf einzelne Eigenschaften der Klasse zuzugreifen, indem Sie die Punktsyntax verwenden:
<h2>New Topping: @Topping.Name</h2>
<p>Ingredients: @Topping.Ingredients</p>
@code {
[Parameter]
public PizzaTopping Topping { get; set; }
}
In der übergeordneten Komponente legen Sie Parameterwerte mithilfe von Attributen der Tags der untergeordneten Komponente fest. Sie legen einfache Komponenten direkt fest. Bei einem Parameter, der auf einer benutzerdefinierten Klasse basiert, verwenden Sie inline C#-Code, um eine neue Instanz dieser Klasse zu erstellen und die zugehörigen Werte festzulegen:
@page "/pizzas-toppings"
<h1>Our Latest Pizzas and Topping</h1>
<Pizza PizzaName="Hawaiian" PizzaDescription="The one with pineapple" />
<PizzaTopping Topping="@(new PizzaTopping() { Name = "Chilli Sauce", Ingredients = "Three kinds of chilli." })" />
Informationen teilen mithilfe von kaskadierenden Parametern
Komponentenparameter funktionieren gut, wenn Sie einen Wert an das unmittelbare untergeordnete Element einer Komponente übergeben möchten. Wenn Sie eine vielschichtige Hierarchie mit mehrfach untergeordneten Elementen verwenden, wird es aber kompliziert. Komponentenparameter werden nicht automatisch an Enkelkomponenten von Vorläuferkomponenten oder im weiteren Verlauf der Hierarchie übergeben. Um dieses Problem elegant zu behandeln, enthält Blazor kaskadierende Parameter. Wenn Sie den Wert eines Kaskadierenden Parameters in einer Komponente festlegen, ist dessen Wert automatisch für alle untergeordneten Komponenten in jeder Tiefe verfügbar.
In der übergeordneten Komponente werden durch die Verwendung des Tags <CascadingValue> die Informationen angegeben, die an alle nachgeordneten Komponenten weitergegeben werden. Dieses Tag wird als integrierte Blazor-Komponente implementiert. Jede komponente, die innerhalb dieses Tags gerendert wird, kann auf den Wert zugreifen.
@page "/specialoffers"
<h1>Special Offers</h1>
<CascadingValue Name="DealName" Value="Throwback Thursday">
<!-- Any descendant component rendered here will be able to access the cascading value. -->
</CascadingValue>
In den untergeordneten Komponenten können Sie auf den kaskadierenden Wert zugreifen, indem Sie Komponentenmitglieder verwenden und sie mit dem [CascadingParameter]-Attribut versehen.
<h2>Deal: @DealName</h2>
@code {
[CascadingParameter(Name="DealName")]
private string DealName { get; set; }
}
In diesem Beispiel verfügt das <h2> Element über den Inhalt Deal: Throwback Thursday, da eine Vorgängerkomponente diesen Kaskadenwert festlegt.
Note
Wie bei Komponentenparametern können Sie Objekte als Kaskadierende Parameter übergeben, wenn Sie komplexere Anforderungen haben.
Im vorherigen Beispiel identifiziert das Name Attribut im übergeordneten Attribut den kaskadierenden Wert, der mit dem Name Wert im [CascadingParameter] Attribut übereinstimmt. Sie können diese Namen optional weglassen, in diesem Fall werden die Attribute nach Typ abgeglichen. Das Weglassen des Namens funktioniert gut, wenn Nur ein Parameter dieses Typs vorhanden ist. Wenn Sie zwei unterschiedliche Zeichenfolgenwerte überlappen möchten, müssen Sie Parameternamen verwenden, um Mehrdeutigkeiten zu vermeiden.
Freigeben von Informationen mithilfe von AppState
Ein weiterer Ansatz zum Austausch von Informationen zwischen verschiedenen Komponenten ist die Verwendung des AppState-Musters. Sie erstellen eine Klasse, die die zu speichernden Eigenschaften definiert und als bereichsbezogenen Dienst registriert. In jeder Komponente, in der Sie die AppState-Werte festlegen oder verwenden möchten, fügen Sie den Dienst ein, und dann können Sie auf dessen Eigenschaften zugreifen. Im Gegensatz zu Komponentenparametern und kaskadierenden Parametern sind Werte in AppState für alle Komponenten in der Anwendung verfügbar, auch Komponenten, die nicht untergeordnete Elemente der Komponente sind, die den Wert gespeichert haben.
Betrachten Sie als Beispiel diese Klasse, in der ein Wert zum Umsatz gespeichert wird:
public class PizzaSalesState
{
public int PizzasSoldToday { get; set; }
}
Sie fügen die Klasse als bereichsbezogenen Dienst in der datei Program.cs hinzu:
...
// Add services to the container
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
// Add the AppState class
builder.Services.AddScoped<PizzaSalesState>();
...
Nun können Sie in jeder Komponente, in der Sie AppState-Werte festlegen oder abrufen möchten, die Klasse einfügen und dann auf Eigenschaften zugreifen:
@page "/"
@inject PizzaSalesState SalesState
<h1>Welcome to Blazing Pizzas</h1>
<p>Today, we've sold this many pizzas: @SalesState.PizzasSoldToday</p>
<button @onclick="IncrementSales">Buy a Pizza</button>
@code {
private void IncrementSales()
{
SalesState.PizzasSoldToday++;
}
}
Note
Dieser Code implementiert einen Indikator, der erhöht wird, wenn der Benutzer eine Schaltfläche auswählt, ähnlich wie das Beispiel im Blazor-Lernprogramm – Erstellen Sie Ihre erste Blazor-App. Der Unterschied besteht darin, dass in diesem Fall der Wert des Zählers in einem AppState-Bereichsdienst gespeichert wurde. Mit unserer bereichsbezogenen Dienstklasse kann die Anzahl über Seitenladevorgänge hinweg beibehalten werden, und andere Benutzer können sie sehen.
In der nächsten Einheit probieren Sie es selbst aus!