Gemeinsames Nutzen von Daten in Blazor-Anwendungen

Abgeschlossen

Blazor bietet mehrere Möglichkeiten, um Informationen für mehrere Komponenten gemeinsam zu nutzen. 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 jeder Komponente in der Anwendung darauf zugreifen können.

Angenommen, Sie arbeiten an der neuen Website des Pizzalieferdiensts. Es sollen mehrere Pizzas auf der Startseite auf gleiche Weise angezeigt werden. Sie möchten die Pizzen anzeigen, indem Sie für jede Pizza eine untergeordnete Komponente rendern. Es soll eine ID an diese untergeordnete Komponente übergeben werden, die bestimmt, welche Pizza angezeigt wird. Sie möchten außerdem einen Wert für mehrere Komponenten speichern und anzeigen, der die Gesamtzahl der Pizzas angibt, die Sie heute verkauft haben.

In dieser Lerneinheit lernen Sie drei verschiedene Techniken kennen, mit denen Sie Werte für zwei oder mehr Blazor-Komponenten gemeinsam nutzen können.

Gemeinsames Nutzen von Informationen mit anderen Komponenten mithilfe von Komponentenparametern

In einer Blazor-Web-App rendert jede Komponente einen HTML-Teil. Einige Komponenten rendern eine vollständige Seite, während andere kleinere Markupfragmente rendern, z. B. eine Tabelle, ein Formular oder ein einzelnes Steuerelement. Wenn Ihre Komponente nur einen Markupteil rendert, müssen Sie sie als untergeordnete Komponente innerhalb einer übergeordneten Komponente verwenden. Ihre untergeordnete Komponente kann wiederum 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 Fotos von Pizzas 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. Er wird als öffentliche C#-Eigenschaft definiert und mit dem Attribut [Parameter] versehen:

<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 Member der untergeordneten Komponente sind, können Sie sie in Ihrem HTML-Code rendern. Dazu verwenden Sie das reservierte @-Symbol von Blazor, gefolgt vom Namen. Außerdem legt der vorangehende Code oben einen Standardwert für den Parameter PizzaDescription fest. Dieser Wert wird gerendert, wenn die übergeordnete Komponente keinen Wert übergibt. Andernfalls wird er durch den Wert überschrieben, der von der übergeordneten Komponente übergeben wird.

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 wie einen Parameterwert als Komponentenparameter verwenden, um mithilfe der Punktsyntax auf einzelne Eigenschaften der Klasse zuzugreifen:

<h2>New Topping: @Topping.Name</h2>

<p>Ingredients: @Topping.Ingredients</p>

@code {
    [Parameter]
    public PizzaTopping Topping { get; set; }
}

Sie legen Parameterwerte in der übergeordneten Komponente fest, indem Sie Attribute der Tags der untergeordneten Komponente verwenden. Legen Sie einfache Komponenten direkt fest. Wenn ein Parameter auf einer benutzerdefinierten Klasse basiert, verwenden Sie C#-Inlinecode, um eine neue Instanz dieser Klasse zu erstellen und ihre 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." })" />

Gemeinsames Nutzen von Informationen mithilfe von kaskadierenden Parametern

Komponentenparameter eignen sich gut, wenn Sie einen Wert an das unmittelbar 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 von Vorgängerkomponenten an jeweils in der Hierarchie immer weiter untergeordnete Komponenten übergeben. Für einen eleganten Umgang mit diesem Problem enthält Blazor kaskadierende Parameter. Wenn Sie den Wert eines kaskadierenden Parameters in einer Komponente festlegen, steht dieser Wert automatisch allen Nachfolgerkomponenten in beliebiger Hierarchietiefe zur Verfügung.

Verwenden Sie in der übergeordneten Komponente das Tag <CascadingValue>, um die Informationen anzugeben, die an alle Nachfolgerkomponenten kaskadiert 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 Nachfolgerkomponenten können Sie auf den kaskadierenden Wert zugreifen, indem Sie Komponentenmember verwenden und sie mit dem [CascadingParameter]-Attribut versehen.

<h2>Deal: @DealName</h2>

@code {
    [CascadingParameter(Name="DealName")]
    private string DealName { get; set; }
}

In diesem Beispiel hat das <h2>-Tag also den Inhalt Deal: Throwback Thursday, da dieser kaskadierende Wert von einer Vorgängerkomponente festgelegt wurde.

Hinweis

Wie bei Komponentenparametern können Sie Objekte als kaskadierende Parameter übergeben, wenn komplexere Anforderungen bestehen.

Im vorherigen Beispiel wird der kaskadierende Wert durch das Name-Attribut im übergeordneten Element identifiziert, das mit dem Name-Wert im [CascadingParameter]-Attribut abgeglichen wird. Sie können diese Namen optional weglassen. In diesem Fall werden die Attribute nach Typ abgeglichen. Das Auslassen des Namens funktioniert gut, wenn Sie nur einen Parameter dieses Typs verwenden. Wenn Sie zwei verschiedene Zeichenfolgenwerte kaskadieren möchten, müssen Sie Parameternamen verwenden, um Mehrdeutigkeiten zu vermeiden.

Gemeinsames Nutzen von Informationen mithilfe von AppState

Ein weiterer Ansatz zur gemeinsamen Nutzung von Informationen für verschiedene Komponenten ist die Verwendung des AppState-Musters. Sie erstellen eine Klasse, die die Eigenschaften definiert, die Sie speichern möchten, und registrieren sie als bereichsbezogenen Dienst. Sie fügen den Dienst in jeder Komponente ein, in der Sie die AppState-Werte festlegen oder verwenden möchten, und greifen dann auf seine Eigenschaften zu. Im Gegensatz zu Komponentenparametern und kaskadierenden Parametern stehen Werte in AppState allen Komponenten in der Anwendung zur Verfügung, auch Komponenten, die keine untergeordneten Elemente der Komponente sind, in der der Wert gespeichert wurde.

Nehmen wir als Beispiel diese Klasse, die einen Wert zum Umsatz speichert:

public class PizzaSalesState
{
    public int PizzasSoldToday { get; set; }
}

Nun wird die Klasse als bereichsbezogener Dienst in der Datei Program.cs hinzugefügt:

...
// Add services to the container
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

// Add the AppState class
builder.Services.AddScoped<PizzaSalesState>();
...

Jetzt kann in jeder Komponente, in der Sie AppState-Werte festlegen oder abrufen möchten, die Klasse eingefügt und dann auf Eigenschaften zugegriffen werden:

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

Hinweis

Dieser Code implementiert einen Zähler, der erhöht wird, wenn der Benutzer eine Schaltfläche auswählt. Dies ähnelt dem Beispiel im Blazor-Tutorial: Erstellen Ihrer ersten Blazor-App. Der Unterschied ist, dass in diesem Fall die Anzahl über Seitenladevorgänge hinweg beibehalten wird und von anderen Benutzern gesehen werden kann, da der Wert des Zählers in einem bereichsbezogenen AppState-Dienst gespeichert wurde.

In der nächsten Lektion versuchen Sie es selbst!

Überprüfen Sie Ihr Wissen

1.

Blazor-Komponenten können Eingaben in Form von zwei Parametertypen annehmen. Welche sind dies?

2.

Mit welcher der folgenden Anweisungen kann AppState beim Dienstlocator registriert werden?