Wiederverwendbarer Komponenten für Benutzeroberflächen erstellen mit Blazor
Tipp
Diese Inhalte sind ein Auszug aus dem eBook „Blazor for ASP NET Web Forms Developers for Azure“, verfügbar unter .NET Docs oder als kostenlos herunterladbare PDF-Datei, die offline gelesen werden kann.
Ein großer Vorteil von ASP.NET Web Forms: es ermöglicht das Einkapseln wiederverwendbarer Elemente von Benutzeroberflächen-Code in wiederverwendbare Steuerelemente für Benutzeroberflächen. Benutzerdefinierte Steuerelemente können mithilfe von ASCX -Dateien im Markup definiert werden. Auch können aufwändige Server-Steuerelemente in mit kompletter Designer-Unterstützung in Code erstellt werden.
Blazor außerdem wird die Benutzeroberflächen-Kapselung durch Komponenten ist unterstützt. Eine Komponente:
- Ist ein eigenständiger Block Benutzeroberfläche.
- Behält die eigene Zustands-und Renderinglogik bei.
- Kann Ereignishandler für Benutzeroberflächen definieren, an Eingabedaten binden und ihren eigenen Lebenszyklus verwalten.
- Wird in der Regel in einer Razor -Datei mit Razor-Syntax definiert.
Einführung in Razor
Razor ist eine einfache Sprache zur Vorlagenerstellung für Markups, die auf HTML und C# basiert. Mit Razor können Sie nahtlos zwischen Markup und C#-Code wechseln, um die Rendering-Logik für Komponenten zu definieren. Wenn die Razor -Datei kompiliert wird, wird die Renderinglogik auf strukturierte Weise in einer .NET-Klasse aufgezeichnet. Der Name der kompilierten Klasse stammt aus dem Namen der Razor-Datei. Der Namespace wird aus dem standardmäßigen Namespace für das Projekt und dem Ordnerpfad entnommen, oder mithilfe der @namespace
-Anweisung explizit angeben (weitere Informationen zu Razor-Anweisungen siehe unten).
Die Rendering-Logik einer Komponente wird mithilfe von normalem HTML-Markup mit dynamischer Logik erstellt, die mit C# hinzugefügt wurde. Das @
Zeichen wird für den Übergang zu C# verwendet. Razor erkennt in der Regel gut, wenn Sie zurück zu HTML gewechselt haben. Die folgende Komponente rendert z. B. ein <p>
-Tag mit der aktuellen Uhrzeit:
<p>@DateTime.Now</p>
Mit Klammern geben Sie Anfang und Ende eines C#-Ausdrucks explizit an:
<p>@(DateTime.Now)</p>
Außerdem erleichtert Razor die Verwendung der C#-Ablaufsteuerung in Ihrer Renderinglogik. Beispielsweise können Sie einige HTML-Code wie folgt bedingt rendern:
@if (value % 2 == 0)
{
<p>The value was even.</p>
}
Sie können auch eine Liste von Elementen generieren, indem Sie eine normale C#-foreach
-Schleife wie die folgende verwenden:
<ul>
@foreach (var item in items)
{
<li>@item.Text</li>
}
</ul>
Wie bei Anweisungen in ASP.NET Web Forms, steuern Razor-Anweisungen viele Aspekte die Kompilierung einer Razor-Komponente. Zu den Beispielen gehören:
- Namespace
- Basisklasse
- Implementierte Schnittstellen
- Generische Parameter
- Importierte Namespaces
- Routen
Razor-Anweisungen beginnen mit dem @
-Zeichen und werden in der Regel am Anfang einer neuen Zeile am Anfang der Datei verwendet. Die @namespace
-Anweisung definiert z. B. den-Namespace der Komponente:
@namespace MyComponentNamespace
In der folgenden Tabelle sind die verschiedenen Razor-Anweisungen, die in Blazor verwendet werden, sowie deren Pendants in ASP.NET Web Forms zusammengefasst, sofern vorhanden.
Anweisung | Beschreibung | Beispiel | Web Forms-Pendant |
---|---|---|---|
@attribute |
Fügt der Komponente ein Attribut auf Klassenebene hinzu | @attribute [Authorize] |
Keine |
@code |
Fügt der Komponente Klassen-Member hinzu. | @code { ... } |
<script runat="server">...</script> |
@implements |
Implementiert die angegebene Oberfläche | @implements IDisposable |
Verwenden des CodeBehinds |
@inherits |
Erbt von der angegebenen Basisklasse | @inherits MyComponentBase |
<%@ Control Inherits="MyUserControlBase" %> |
@inject |
Fügt einen Dienst in die Komponente ein | @inject IJSRuntime JS |
Keine |
@layout |
Gibt eine Layoutkomponente für die Komponente an. | @layout MainLayout |
<%@ Page MasterPageFile="~/Site.Master" %> |
@namespace |
Legt den Namespace für die Komponente fest | @namespace MyNamespace |
Keine |
@page |
Gibt die Route für die Komponente an. | @page "/product/{id}" |
<%@ Page %> |
@typeparam |
Gibt einen generischen Typparameter für die Komponente an | @typeparam TItem |
Verwenden des CodeBehinds |
@using |
Gibt einen Namespace an, der an den Bereich anzupassen ist | @using MyComponentNamespace |
Namespace hinzufügen in web.config |
Außerdem verwenden Razor-Komponenten vermehrt Anweisungsattribute für Elemente, um verschiedene Aspekte der Kompilierung von Komponenten zu steuern (Ereignis-Handling, Datenbindung, Verweise auf Komponenten und Elemente usw.). Anweisungsattribute folgen allen allgemeinen generischen Syntax, bei der die Werte in Klammern optional sind:
@directive(-suffix(:name))(="value")
In der folgenden Tabelle werden die verschiedenen Attribute der in Blazor verwendeten Razor-Anweisungen zusammengefasst.
attribute | Beschreibung | Beispiel |
---|---|---|
@attributes |
Rendert ein Wörterbuch von Attributen | <input @attributes="ExtraAttributes" /> |
@bind |
Erstellt eine bidirektionale Datenbindung | <input @bind="username" @bind:event="oninput" /> |
@on{event} |
Fügt einen Ereignishandler für das angegebene Element hinzu | <button @onclick="IncrementCount">Click me!</button> |
@key |
Gibt einen Schlüssel an, der vom diffingalgorithmus zum Beibehalten von Elementen in einer Auflistung verwendet werden soll. | <DetailsEditor @key="person" Details="person.Details" /> |
@ref |
Zeichnet einen Verweis auf die Komponente oder das HTML-Element auf | <MyDialog @ref="myDialog" /> |
Die verschiedenen Direktivenattribute, die von Blazor ( @onclick
, @bind
, @ref
usw.) verwendet werden, werden in den Abschnitten unten und in späteren Kapiteln behandelt.
Viele der Syntaxen, die in .aspx und .ascx-Dateien verwendet werden, haben in Razor eine parallele Syntax. Im Folgenden finden Sie einen einfachen Vergleich der Syntaxen für ASP.net Web Forms und Razor.
Funktion | Web Forms | Syntax | Razor | Syntax |
---|---|---|---|---|
Anweisungen | <%@ [directive] %> |
<%@ Page %> |
@[directive] |
@page |
Codeblöcke | <% %> |
<% int x = 123; %> |
@{ } |
@{ int x = 123; } |
Ausdrücke (HTML-codiert) |
<%: %> |
<%:DateTime.Now %> |
Implizit: @ Explizit: @() |
@DateTime.Now @(DateTime.Now) |
Kommentare | <%-- --%> |
<%-- Commented --%> |
@* *@ |
@* Commented *@ |
Datenbindung | <%# %> |
<%# Bind("Name") %> |
@bind |
<input @bind="username" /> |
Verwenden Sie die @code
-Direktive, um der Razor-Komponentenklasse weitere Elemente hinzuzufügen. Dieses Verfahren ähnelt der Verwendung eines <script runat="server">...</script>
-Blocks in einem/einer ASP.NET Web Forms-Benutzersteuerelement oder -Seite.
@code {
int count = 0;
void IncrementCount()
{
count++;
}
}
Da Razor auf C# basiert, muss es in einem C#-Projekt ( .csproj) kompiliert werden. Razor-Dateien können nicht aus einem Visual Basic-Projekt ( .vbproj) kompiliert werden. Sie können weiterhin auf Visual Basic-Projekte aus Ihrem Blazor-Projekt verweisen. Das Gegenteil ist auch der Fall.
Eine vollständige Razor-Syntaxreferenz finden Sie unter Razor-Syntaxreferenz für ASP.NET Core.
Verwenden von Komponenten
Abgesehen von normalem HTML können Komponenten auch andere Komponenten als Teil ihrer Rendering-Logik verwenden. Die Syntax für die Verwendung einer Komponente in Razor ähnelt der Verwendung eines Benutzersteuerelements in einer ASP.NET Web Forms-App. Komponenten werden mithilfe eines Elementtags angegeben, das mit dem Typnamen der Komponente übereinstimmt. Sie können beispielsweise eine Counter
-Komponente wie diese hinzufügen:
<Counter />
Im Gegensatz zu ASP.NET Web Forms, verwenden Komponenten in Blazor:
- kein Elementpräfix (z. B.
asp:
). - Sie müssen nicht auf der Seite oder in der web.configregistriert werden.
Stellen Sie sich die Razor-Komponenten wie .NET-Typen vor, denn genau das sind sie. Wenn auf die Assembly verwiesen wird, die die Komponente enthält, kann die Komponente verwendet werden. Um den Namespace der Komponente dem Bereich entsprechend anzupassen, wenden Sie die @using
-Anweisung an:
@using MyComponentLib
<Counter />
Wie in den standardmäßigen Blazor-Projekten zu sehen ist, werden @using
-Direktiven häufig in eine _Imports.razor-Datei eingefügt, sodass Sie in alle .razor-Dateien im gleichen Verzeichnis und in untergeordneten Verzeichnissen importiert werden.
Wenn sich der Namespace für eine Komponente nicht im Gültigkeitsbereich befindet, können Sie eine Komponente mit dem vollständigen Typnamen wie in C# angeben:
<MyComponentLib.Counter />
Ändern des Seitentitels über Komponenten
Bei der Erstellung von Apps im SPA-Stil ist es üblich, dass Teile einer Seite neu geladen werden, ohne die gesamte Seite neu zu laden. Dennoch kann, abhängig von der zurzeit geladenen Komponente, eine Änderung des Seitentitels sinnvoll sein. Hierzu können Sie das <PageTitle>
-Tag in die Razor-Seite der Komponente einfügen:
@page "/"
<PageTitle>Home</PageTitle>
Der Inhalt dieses Elements kann dynamisch sein und z. B. die aktuelle Anzahl von Meldungen anzeigen:
<PageTitle>@MessageCount messages</PageTitle>
Beachten Sie Folgendes: Wenn mehrere Komponenten auf einer bestimmten Seite <PageTitle>
-Tags enthalten, wird nur die letzte Komponente angezeigt (da jede Komponente die vorherige überschreibt).
Komponentenparameter
In ASP.NET Web Forms können Sie mithilfe der Öffentlichen Eigenschaften Parameter und Daten an Steuerelemente weiterleiten. Diese Eigenschaften können im Markup mithilfe von Attributen oder direkt im Code festgelegt werden. Razor-Komponenten funktionieren in ähnlicher Weise, obwohl die Komponenteneigenschaften auch mit dem [Parameter]
-Attribut gekennzeichnet werden müssen, um als Komponentenparameter angesehen zu werden.
Die folgende Counter
-Komponente definiert einen Komponentenparameter mit dem Namen IncrementAmount
, der verwendet werden kann, um den Betrag anzugeben, der bei Counter
bei jedem Klicken auf die Schaltfläche erhöht werden soll.
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
int currentCount = 0;
[Parameter]
public int IncrementAmount { get; set; } = 1;
void IncrementCount()
{
currentCount+=IncrementAmount;
}
}
Verwenden Sie ein Attribut wie in ASP.net Web Forms, um einen Komponentenparameter in Blazor anzugeben:
<Counter IncrementAmount="10" />
Abfragezeichenfolge-Parameter
Razor-Komponenten können auch Werte aus der Abfragezeichenfolge der Seite, auf der sie gerendert werden, als Parameterquelle nutzen. Fügen Sie zur Aktivierung dieses Verhaltens dem Parameter das [SupplyParameterFromQuery]
-Attribut hinzu. Die folgende Parameterdefinition würde ihren Wert beispielsweise in der Form ?IncBy=2
aus der Anforderung erhalten:
[Parameter]
[SupplyParameterFromQuery(Name = "IncBy")]
public int IncrementAmount { get; set; } = 1;
Wenn Sie keinen benutzerdefinierten Name
-Wert im [SupplyParameterFromQuery]
-Attribut angeben, wird standardmäßig der Eigenschaftsname verwendet (in diesem Fall IncrementAmount
).
Komponenten und Fehlergrenzen
Standardmäßig erkennen Blazor-Apps unbehandelte Ausnahmen und zeigen unten auf der Seite eine Fehlermeldung ohne weitere Details an. Um die Teile der App einzuschränken, die von einem unbehandelten Fehler betroffen sind, z. B. um die Auswirkungen auf eine einzelne Komponente zu begrenzen, können Komponentendeklarationen mit dem <ErrorBoundary>
-Tag umschlossen werden.
Um sich beispielsweise vor möglichen Ausnahmen zu schützen, die von der Counter
-Komponente ausgelöst werden, deklarieren Sie diese innerhalb einer <ErrorBoundary>
-Komponente und geben optional eine Meldung an, die im Falle einer Ausnahme angezeigt wird:
<ErrorBoundary>
<ChildContent>
<Counter />
</ChildContent>
<ErrorContent>
Oops! The counter isn't working right now; please try again later.
</ErrorContent>
</ErrorBoundary>
Wenn Sie keinen benutzerdefinierten Fehlerinhalt angeben müssen, können Sie die Komponente einfach direkt umschließen:
<ErrorBoundary>
<Counter />
</ErrorBoundary>
Wenn in der umschlossenen Komponente eine nicht behandelte Ausnahme auftritt, wird die Standardmeldung „Ein Fehler ist aufgetreten.“ angezeigt.
Ereignishandler
Beide ASP.NET Web Forms und Blazor stellen ein auf Ereignissen basiertes Programmiermodell für die Behandlung von Benutzeroberflächenereignissen bereit. Beispiele für derartige Ereignisse sind Klicks auf Schaltflächen und Texteingaben. In ASP.NET Web Forms verwenden Sie HTML-Serversteuerelemente zur Handhabung von Benutzeroberflächenereignissen, die vom DOM verfügbar gemacht werden, oder Sie können Ereignisse behandeln, die von Webserver-Steuerelementen verfügbar gemacht werden. Die Ereignisse werden auf dem Server über Formular-Post-Back Anforderungen angezeigt. Beachten Sie die folgenden Beispiele für Klicks auf Schaltflächen in Web Forms Schaltflächen:
Counter.ascx
<asp:Button ID="ClickMeButton" runat="server" Text="Click me!" OnClick="ClickMeButton_Click" />
Counter.ascx.cs
public partial class Counter : System.Web.UI.UserControl
{
protected void ClickMeButton_Click(object sender, EventArgs e)
{
Console.WriteLine("The button was clicked!");
}
}
In Blazor können Sie Handler für DOM-UI-Ereignisse direkt mithilfe von Direktivenattributen im Formular registrieren @on{event}
. Der {event}
-Platzhalter stellt den Namen Ihres Elements dar. Beispielsweise können Sie Klicks auf Schaltflächen wie folgt auflisten:
<button @onclick="OnClick">Click me!</button>
@code {
void OnClick()
{
Console.WriteLine("The button was clicked!");
}
}
Ereignishandler können ein optionales, für ein Ereignis spezifisches Argument akzeptieren, um weitere Informationen zum Ereignis bereitzustellen. Mausereignisse können z. B. ein MouseEventArgs
-Argument annehmen, aber es ist nicht erforderlich.
<button @onclick="OnClick">Click me!</button>
@code {
void OnClick(MouseEventArgs e)
{
Console.WriteLine($"Mouse clicked at {e.ScreenX}, {e.ScreenY}.");
}
}
Anstatt auf eine Methodengruppe für einen Ereignishandler zu verweisen, können Sie einen Lambdaausdruck verwenden. Ein Lambdaausdruck ermöglicht es Ihnen, andere Werte im Gültigkeitsbereich zu schließen.
@foreach (var buttonLabel in buttonLabels)
{
<button @onclick="() => Console.WriteLine($"The {buttonLabel} button was clicked!")">@buttonLabel</button>
}
Ereignishandler können synchron oder asynchron ausgeführt werden. Der folgende OnClick
Ereignishandler wird z. B. asynchron ausgeführt:
<button @onclick="OnClick">Click me!</button>
@code {
async Task OnClick()
{
var result = await Http.GetAsync("api/values");
}
}
Nachdem ein Ereignis behandelt wurde, wird die Komponente gerendert, um alle Änderungen des Komponentenzustands zu berücksichtigen. Bei asynchronen Ereignishandlern wird die Komponente unmittelbar nach Abschluss der Handlerausführung gerendert. Die Komponente wird wieder gerendert, nachdem der asynchrone Task
abgeschlossen wurde. Dieser asynchrone Ausführungsmodus bietet die Möglichkeit, eine geeignete Benutzeroberfläche zu rendern, während der asynchrone Task
noch ausgeführt wird.
<button @onclick="ShowMessage">Get message</button>
@if (showMessage)
{
@if (message == null)
{
<p><em>Loading...</em></p>
}
else
{
<p>The message is: @message</p>
}
}
@code
{
bool showMessage = false;
string message;
public async Task ShowMessage()
{
showMessage = true;
message = await MessageService.GetMessageAsync();
}
}
Komponenten können auch eigene Ereignisse definieren, indem Sie einen Komponenten Parameter vom Typ EventCallback<TValue>
definieren. Ereignisrückrufe unterstützen alle Variationen von DOM-UI-Ereignishandlern: optionale Argumente, synchrone oder asynchrone Methoden, Methodengruppen oder Lambdaausdrücke.
<button class="btn btn-primary" @onclick="OnClick">Click me!</button>
@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClick { get; set; }
}
Datenbindung
Blazor stellt einen einfachen Mechanismus bereit, mit dem Daten aus einer Benutzeroberflächenkomponente an den Status der Komponente gebunden werden können. Diese Vorgehensweise unterscheidet sich von den Features in ASP.NET Web Forms für das Binden von Daten aus Datenquellen an UI-Steuerelemente. Im Abschnitt Umgang mit Daten wird die Behandlung von Daten aus verschiedenen Datenquellen behandelt.
Verwenden Sie zum Erstellen einer bidirektionalen Datenbindung von einer Benutzeroberflächenkomponente zum Status der Komponente das @bind
-Direktivenattribut. Im folgenden Beispiel ist der Wert des Kontrollkästchens an das isChecked
-Feld gebunden.
<input type="checkbox" @bind="isChecked" />
@code {
bool isChecked;
}
Wenn die Komponente gerendert wird, wird der Wert des Kontrollkästchens auf den Wert des isChecked
-Felds festgelegt. Wenn der Benutzer das Kontrollkästchen schaltet, wird das onchange
-Ereignis ausgelöst, und das isChecked
-Feld wird auf den neuen Wert festgelegt. Die @bind
-Syntax in diesem Fall entspricht dem folgenden Markup:
<input value="@isChecked" @onchange="(UIChangeEventArgs e) => isChecked = e.Value" />
Verwenden Sie das @bind:event
-Attribut, um das für die Bindung verwendete Ereignis zu ändern.
<input @bind="text" @bind:event="oninput" />
<p>@text</p>
@code {
string text;
}
Komponenten können auch die Datenbindung an Ihre Parameter unterstützen. Definieren Sie für die Datenbindung einen Ereignisrückruf-Parameter mit dem gleichen Namen wie der Parameter, der gebunden werden kann. Das Suffix „Changed“ wird dem Namen hinzugefügt.
PasswordBox.razor
Password: <input
value="@Password"
@oninput="OnPasswordChanged"
type="@(showPassword ? "text" : "password")" />
<label><input type="checkbox" @bind="showPassword" />Show password</label>
@code {
private bool showPassword;
[Parameter]
public string Password { get; set; }
[Parameter]
public EventCallback<string> PasswordChanged { get; set; }
private Task OnPasswordChanged(ChangeEventArgs e)
{
Password = e.Value.ToString();
return PasswordChanged.InvokeAsync(Password);
}
}
Wenn Sie eine Datenbindung an ein zugrundeliegendes UI-Element verketten möchten, legen Sie den Wert fest, und behandeln Sie das Ereignis direkt für das UI-Element, anstatt das @bind
-Attribut zu verwenden.
Verwenden Sie zum Binden an einen Komponentenparameter ein @bind-{Parameter}
-Attribut, um den Parameter anzugeben, an den die Bindung erfolgen soll.
<PasswordBox @bind-Password="password" />
@code {
string password;
}
Statusänderungen
Wenn sich der Zustand der Komponente außerhalb eines normalen UI-Ereignisses oder Ereignisrückrufs geändert hat, muss die Komponente manuell signalisieren, dass Sie erneut gerendert werden muss. Um zu signalisieren, dass sich der Status einer Komponente geändert hat, müssen Sie die StateHasChanged
-Methode für die Komponente aufrufen.
Im folgenden Beispiel zeigt eine Komponente eine Nachricht von einem AppState
-Dienst an, der von anderen Teilen der APP aktualisiert werden kann. Die Komponente registriert die StateHasChanged
-Methode mit dem AppState.OnChange
-Ereignis, sodass die Komponente immer dann gerendert wird, wenn die Nachricht aktualisiert wird.
public class AppState
{
public string Message { get; }
// Lets components receive change notifications
public event Action OnChange;
public void UpdateMessage(string message)
{
Message = message;
NotifyStateChanged();
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
@inject AppState AppState
<p>App message: @AppState.Message</p>
@code {
protected override void OnInitialized()
{
AppState.OnChange += StateHasChanged
}
}
Ereignisse des Komponentenlebenszyklus:
Das Framework von ASP.NET Web Forms verfügt über klar definierte Lebenszyklusmethoden für Module, Seiten und Steuerelemente. Das folgende Steuerelement implementiert z. B. Ereignishandler für das Init
, Load
,und UnLoad
-Lebenszyklusereignis:
Counter.ascx.cs
public partial class Counter : System.Web.UI.UserControl
{
protected void Page_Init(object sender, EventArgs e) { ... }
protected void Page_Load(object sender, EventArgs e) { ... }
protected void Page_UnLoad(object sender, EventArgs e) { ... }
}
Razor-Komponenten verfügen auch über einen klar definierten Lebenszyklus. Der Lebenszyklus einer Komponente kann verwendet werden, um den Komponentenstatus zu initialisieren und erweiterte Komponentenverhalten zu implementieren.
Alle Lebenszyklusmethoden der Blazor-Komponenten haben synchrone und asynchrone Versionen. Das Komponentenrendering ist synchron. Asynchrone Logik kann nicht als Teil des Komponentenrendering ausgeführt werden. Jede asynchrone Logik muss als Teil einer async
-Lebenszyklusmethode ausgeführt werden.
OnInitialized
Die OnInitialized
und OnInitializedAsync
-Methoden werden verwendet, um die Komponente zu initialisieren. Eine Komponente wird in der Regel initialisiert, nachdem Sie erstmals gerendert wurde. Nachdem eine Komponente initialisiert wurde, kann Sie mehrmals gerendert werden, bevor Sie schließlich verworfen wird. Die OnInitialized
-Methode ähnelt dem Page_Load
-Ereignis in ASP.NET Web Forms-Seiten und -Steuerelementen.
protected override void OnInitialized() { ... }
protected override async Task OnInitializedAsync() { await ... }
OnParametersSet
Die OnParametersSet
-Methode und die OnParametersSetAsync
-Methode werden aufgerufen, wenn eine Komponente Parameter von ihrem übergeordneten Element erhalten hat und dem Wert Eigenschaften zugewiesen werden. Diese Methoden werden nach der Initialisierung der Komponente und jedes Mal, wenn die Komponente gerendert wird, ausgeführt.
protected override void OnParametersSet() { ... }
protected override async Task OnParametersSetAsync() { await ... }
OnAfterRender
OnAfterRender
und OnAfterRenderAsync
werden aufgerufen, nachdem eine Komponente das Rendering beendet hat. Element- und Komponentenverweise werden an diesem Punkt aufgefüllt (Weitere Informationen zu diesen Konzepten finden Sie unten). Die Interaktivität mit dem Browser ist an diesem Punkt aktiviert. Interaktionen mit der DOM- und JavaScript-Ausführung können problemlos erfolgen.
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
...
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await ...
}
}
OnAfterRender
und OnAfterRenderAsync
werden beim Prerendering auf dem Server nicht aufgerufen.
Der firstRender
-Parameter beträgt das erste Mal, wenn die Komponente gerendert wird, true
, andernfalls ist der Wert false
.
IDisposable
Razor-Komponenten können IDisposable
implementieren, um Ressourcen freizugeben, wenn die Komponente aus der Benutzeroberfläche entfernt wird. Eine Razor-Komponente kann IDispose
mithilfe der @implements
-Direktive implementieren:
@using System
@implements IDisposable
...
@code {
public void Dispose()
{
...
}
}
Komponentenreferenzen aufzeichnen
In ASP.NET Web Forms ist es üblich, eine Steuerelementinstanz direkt im Code zu bearbeiten, indem sie sich auf ihre ID bezieht. In Blazor ist es auch möglich, einen Verweis auf eine Komponente zu erfassen und zu bearbeiten, obwohl sie viel weniger häufig ist.
Um einen Komponentenverweis in Blazor zu erfassen, verwenden Sie das @ref
-Direktivenattribut. Der Wert des Attributs sollte mit dem Namen eines festlegbaren Felds mit dem gleichen Typ wie die Komponente übereinstimmen, auf die verwiesen wird.
<MyLoginDialog @ref="loginDialog" ... />
@code {
MyLoginDialog loginDialog = default!;
void OnSomething()
{
loginDialog.Show();
}
}
Wenn die Parent-Komponente gerendert wird, wird das Feld mit der untergeordneten Komponenteninstanz aufgefüllt. Anschließend können Sie Methoden für die Komponenteninstanz aufrufen oder sie anderweitig bearbeiten.
Das direkte Bearbeiten des Komponentenzustands mithilfe von Komponentenverweisen ist nicht empfehlenswert. Dadurch wird verhindert, dass die Komponente automatisch zu den richtigen Zeitpunkten gerendert wird.
Elementverweise aufzeichnen
Razor-Komponenten können Verweise auf ein Element aufzeichnen. Im Gegensatz zu HTML-Server Steuerelementen in ASP.NET-Web Forms können Sie das DOM nicht direkt mithilfe eines Elementverweises inBlazor bearbeiten. Blazor behandelt die meisten DOM-Interaktionen für Sie mithilfe des Dom-Diffing-Algorithmus. Aufgezeichnete Elementverweise in Blazor sind nicht transparent. Sie werden jedoch verwendet, um einen bestimmten Elementverweis in einem JavaScript-Interop-Befehl zu übergeben. Weitere Informationen zum JavaScript-Interop finden Sie unter ASP.NET Core Blazor JavaScript-Interop.
Komponenten mit Vorlagen
In ASP.NET Web Forms können Sie Steuerlemente mit Vorlagen erstellen. Mithilfe von Steuerelementen mit Vorlagen kann der Entwickler einen Teil des HTML-Code angeben, der zum Rendering eines Containersteuerelements verwendet wird. Die Mechanismen der Erstellung von Serversteuerelementen mit Vorlagen sind komplex, aber sie ermöglichen leistungsstarke Szenarios zum Rendern von Daten auf eine an den Benutzer anpassbare Weise. Beispiele für Steuerelemente mit Vorlagen sind Repeater
und DataList
.
Razor-Komponenten können auch durch Definition von Komponentenparametern vom Typ RenderFragment
oder RenderFragment<T>
durch Vorlagen erstellt werden. Ein RenderFragment
stellt einen Block von Razor-Markup dar, der dann von der Komponente gerendert werden kann. Ein RenderFragment<T>
ist ein Block von Razor-Markup, der einen Parameter annimmt, der beim Rendern des Renderingfragments angegeben werden kann.
Untergeordneter Inhalt
Razor-Komponenten können ihren untergeordneten Inhalt als ein RenderFragment
erfassen und diesen Inhalt als Teil des Komponentenrendering rendern. Zum Erfassen von untergeordnetem Inhalt definieren Sie einen Komponentenparameter vom Typ RenderFragment
und benennen Sie ihn ChildContent
.
ChildContentComponent.razor
<h1>Component with child content</h1>
<div>@ChildContent</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
Eine übergeordnete Komponente kann dann untergeordneten Inhalt mithilfe von normalem Razor-Syntax bereitstellen.
<ChildContentComponent>
<ChildContent>
<p>The time is @DateTime.Now</p>
</ChildContent>
</ChildContentComponent>
Vorlagenparameter
Eine auf Vorlagen basierende Razor-Komponente kann auch mehrere Komponentenparameter vom Typ RenderFragment
oder RenderFragment<T>
definieren. Der Parameter für einen RenderFragment<T>
kann angegeben werden, wenn er aufgerufen wird. Um einen generischen Typparameter für eine Komponente anzugeben, verwenden Sie die @typeparam
-Razor-Direktive.
SimpleListView.razor
@typeparam TItem
@Heading
<ul>
@foreach (var item in Items)
{
<li>@ItemTemplate(item)</li>
}
</ul>
@code {
[Parameter]
public RenderFragment Heading { get; set; }
[Parameter]
public RenderFragment<TItem> ItemTemplate { get; set; }
[Parameter]
public IEnumerable<TItem> Items { get; set; }
}
Bei der Verwendung einer Komponentenvorlage werden die Vorlagenparameter mithilfe eines untergeordneten Elements angegeben, das mit den Namen der Parameter übereinstimmt. Komponentenargumente vom Typ RenderFragment<T>
als Element weitergegeben verfügen über einen impliziten Parameter mit dem Namen context
. Sie können den Namen dieses Implementparameters mithilfe des Context
-Attributs für das untergeordnete Element ändern. Jeder Typparameter kann mithilfe eines Attributs angegeben werden, der mit dem Namen des Typparameters übereinstimmt. Der Typparameter wird nach Möglichkeit abgeleitet:
<SimpleListView Items="messages" TItem="string">
<Heading>
<h1>My list</h1>
</Heading>
<ItemTemplate Context="message">
<p>The message is: @message</p>
</ItemTemplate>
</SimpleListView>
Die Ausgabe dieser Komponente sieht folgendermaßen aus:
<h1>My list</h1>
<ul>
<li><p>The message is: message1</p></li>
<li><p>The message is: message2</p></li>
<ul>
CodeBehind
Eine Razor-Komponente wird in der Regel in einer einzelnen .razor-Datei erstellt. Es ist jedoch auch möglich, den Code und das Markup mithilfe einer CodeBehind-Datei zu trennen. Um eine Komponentendatei zu verwenden, fügen Sie eine C#-Datei hinzu, die mit dem Dateinamen der Komponentendatei übereinstimmt, jedoch mit der Erweiterung .cs (Counter.razor.cs). Verwenden Sie die C#-Datei, um eine Basisklasse für die Komponente zu definieren. Sie können der Basisklasse einen beliebigen Namen benennen, aber es ist üblich, die Klasse mit der Komponentenklasse zu benennen, aber mit einer hinzugefügten Base
-Erweiterung (CounterBase
). Die komponentenbasierte Klasse muss auch von ComponentBase
abgeleitet werden. Fügen Sie dann in der Razor-Komponentendatei die @inherits
-Direktive hinzu, um die Basisklasse für die Komponente (@inherits CounterBase
) anzugeben.
Counter.razor
@inherits CounterBase
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>
Counter.razor.cs
public class CounterBase : ComponentBase
{
protected int currentCount = 0;
protected void IncrementCount()
{
currentCount++;
}
}
Die Sichtbarkeit der Komponentenelemente in der Basisklasse muss protected
oder public
sein, um für die Komponentenklasse sichtbar zu sein.
Zusätzliche Ressourcen
Die vorhergehende Behandlung aller Aspekte von Razor-Komponenten ist nicht vollständig. Weitere Informationen zum Erstellen und Verwenden von ASP.NET Core Razor-Komponentenfinden Sie in der Blazor-Dokumentation.