Udostępnij za pośrednictwem


Kompilowanie składników interfejsu użytkownika wielokrotnego użytku za pomocą polecenia Blazor

Napiwek

Ta zawartość jest fragmentem książki eBook Blazor dla deweloperów formularzy internetowych platformy ASP NET dla platformy Azure, dostępnym na platformie .NET Docs lub jako bezpłatny plik PDF do pobrania, który można odczytać w trybie offline.

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover thumbnail (Miniatura książki eBook for-ASP-NET-Web-Forms-Developers).

Jedną z pięknych rzeczy dotyczących ASP.NET Web Forms jest to, jak umożliwia hermetyzację fragmentów kodu interfejsu użytkownika wielokrotnego użytku do kontrolek interfejsu użytkownika wielokrotnego użytku. Niestandardowe kontrolki użytkownika można zdefiniować w znacznikach przy użyciu plików ascx . Możesz również utworzyć rozbudowane kontrolki serwera w kodzie z pełną obsługą projektanta.

Blazor Obsługuje również hermetyzację interfejsu użytkownika za pośrednictwem składników. Składnik:

  • To samodzielny fragment interfejsu użytkownika.
  • Utrzymuje własny stan i logikę renderowania.
  • Może definiować programy obsługi zdarzeń interfejsu użytkownika, wiązać się z danymi wejściowymi i zarządzać własnym cyklem życia.
  • Jest zwykle definiowany w pliku razor przy użyciu składni Razor.

Wprowadzenie do razor

Razor to lekki język tworzenia szablonów znaczników oparty na językach HTML i C#. Dzięki platformie Razor można bezproblemowo przechodzić między znacznikami i kodem języka C#, aby zdefiniować logikę renderowania składników. Po skompilowaniu pliku razor logika renderowania jest przechwytywana w ustrukturyzowany sposób w klasie .NET. Nazwa skompilowanej klasy jest pobierana z nazwy pliku razor . Przestrzeń nazw jest pobierana z domyślnej przestrzeni nazw projektu i ścieżki folderu lub można jawnie określić przestrzeń nazw przy użyciu @namespace dyrektywy (więcej informacji na temat dyrektyw Razor poniżej).

Logika renderowania składnika jest utworzona przy użyciu normalnego znaczników HTML z dynamiczną logiką dodaną przy użyciu języka C#. Znak @ jest używany do przejścia do języka C#. Razor jest zwykle inteligentny w rozwiązywaniu, gdy przełączono się z powrotem do kodu HTML. Na przykład następujący składnik renderuje <p> tag o bieżącej godzinie:

<p>@DateTime.Now</p>

Aby jawnie określić początek i koniec wyrażenia języka C#, użyj nawiasów:

<p>@(DateTime.Now)</p>

Platforma Razor ułatwia również korzystanie z przepływu sterowania języka C# w logice renderowania. Na przykład możesz warunkowo renderować kod HTML w następujący sposób:

@if (value % 2 == 0)
{
    <p>The value was even.</p>
}

Możesz też wygenerować listę elementów przy użyciu normalnej pętli języka C# foreach , takiej jak poniżej:

<ul>
@foreach (var item in items)
{
    <li>@item.Text</li>
}
</ul>

Dyrektywy Razor, takie jak dyrektywy w ASP.NET Web Forms, kontrolują wiele aspektów kompilowania składnika Razor. Przykłady obejmują składniki:

  • Przestrzeń nazw
  • Klasa bazowa
  • Zaimplementowane interfejsy
  • Parametry ogólne
  • Zaimportowane przestrzenie nazw
  • Trasy

Dyrektywy Razor zaczynają się od @ znaku i są zwykle używane na początku nowego wiersza na początku pliku. Na przykład @namespace dyrektywa definiuje przestrzeń nazw składnika:

@namespace MyComponentNamespace

Poniższa tabela zawiera podsumowanie różnych dyrektyw Razor używanych w programie Blazor i ich odpowiedników ASP.NET Web Forms, jeśli istnieją.

Dyrektywa opis Przykład Odpowiednik formularzy sieci Web
@attribute Dodaje atrybut na poziomie klasy do składnika @attribute [Authorize] Brak
@code Dodaje składowe klasy do składnika @code { ... } <script runat="server">...</script>
@implements Implementuje określony interfejs @implements IDisposable Używanie kodu za pomocą kodu
@inherits Dziedziczy z określonej klasy bazowej @inherits MyComponentBase <%@ Control Inherits="MyUserControlBase" %>
@inject Wstrzykiwanie usługi do składnika @inject IJSRuntime JS Brak
@layout Określa składnik układu składnika @layout MainLayout <%@ Page MasterPageFile="~/Site.Master" %>
@namespace Ustawia przestrzeń nazw składnika @namespace MyNamespace Brak
@page Określa trasę dla składnika @page "/product/{id}" <%@ Page %>
@typeparam Określa ogólny parametr typu składnika @typeparam TItem Używanie kodu za pomocą kodu
@using Określa przestrzeń nazw do uwzględnienia w zakresie @using MyComponentNamespace Dodawanie przestrzeni nazw w pliku web.config

Składniki Razor umożliwiają również szerokie wykorzystanie atrybutów dyrektywy dla elementów w celu kontrolowania różnych aspektów sposobu kompilowania składników (obsługa zdarzeń, wiązanie danych, odwołania do składników i elementów itd.). Atrybuty dyrektywy są zgodne ze wspólną składnią ogólną, w której wartości w nawiasach są opcjonalne:

@directive(-suffix(:name))(="value")

W poniższej tabeli przedstawiono podsumowanie różnych atrybutów dyrektyw Razor używanych w programie Blazor.

Atrybut opis Przykład
@attributes Renderuje słownik atrybutów <input @attributes="ExtraAttributes" />
@bind Tworzy dwukierunkowe powiązanie danych <input @bind="username" @bind:event="oninput" />
@on{event} Dodaje procedurę obsługi zdarzeń dla określonego zdarzenia <button @onclick="IncrementCount">Click me!</button>
@key Określa klucz, który ma być używany przez algorytm różnicowania w celu zachowania elementów w kolekcji <DetailsEditor @key="person" Details="person.Details" />
@ref Przechwytuje odwołanie do składnika lub elementu HTML <MyDialog @ref="myDialog" />

Różne atrybuty dyrektywy używane przez Blazor (@onclick, @bind, @refi tak dalej) zostały omówione w poniższych sekcjach i w kolejnych rozdziałach.

Wiele składni używanych w plikach .aspx i .ascx ma składnie równoległe w środowisku Razor. Poniżej przedstawiono proste porównanie składni ASP.NET Web Forms i Razor.

Funkcja Formularze sieci Web Składnia Razor Składnia
Dyrektyw <%@ [directive] %> <%@ Page %> @[directive] @page
Bloki kodu <% %> <% int x = 123; %> @{ } @{ int x = 123; }
Wyrażenia
(zakodowany w formacie HTML)
<%: %> <%:DateTime.Now %> Niejawny: @
Wyraźny: @()
@DateTime.Now
@(DateTime.Now)
Komentarze <%-- --%> <%-- Commented --%> @* *@ @* Commented *@
Powiązanie danych <%# %> <%# Bind("Name") %> @bind <input @bind="username" />

Aby dodać składowe do klasy składników Razor, użyj @code dyrektywy . Ta technika jest podobna do użycia <script runat="server">...</script> bloku w kontrolce użytkownika lub stronie ASP.NET Web Forms.

@code {
    int count = 0;

    void IncrementCount()
    {
        count++;
    }
}

Ponieważ platforma Razor jest oparta na języku C#, należy ją skompilować z poziomu projektu języka C# (csproj). Nie można skompilować plików razor z projektu Visual Basic (vbproj). Nadal możesz odwoływać się do projektów Visual Basic z Blazor projektu. Odwrotnie jest też prawdą.

Aby uzyskać pełną dokumentację składni Razor, zobacz Dokumentacja składni Razor dla ASP.NET Core.

Używanie składników

Oprócz normalnego kodu HTML składniki mogą również używać innych składników w ramach logiki renderowania. Składnia używania składnika w środowisku Razor jest podobna do używania kontrolki użytkownika w aplikacji ASP.NET Web Forms. Składniki są określane przy użyciu tagu elementu zgodnego z nazwą typu składnika. Możesz na przykład dodać składnik podobny do następującego Counter :

<Counter />

W przeciwieństwie do ASP.NET web forms składniki w programie Blazor:

  • Nie używaj prefiksu elementu (na przykład asp:).
  • Nie wymagaj rejestracji na stronie ani w pliku web.config.

Pomyśl o składnikach Razor, takich jak typy platformy .NET, ponieważ to właśnie one są. Jeśli zestaw zawierający składnik jest przywołyny, składnik jest dostępny do użycia. Aby przenieść przestrzeń nazw składnika do zakresu, zastosuj dyrektywę @using :

@using MyComponentLib

<Counter />

Jak widać w projektach domyślnychBlazor, często umieszcza @using się dyrektywy w pliku _Imports.razor, aby były importowane do wszystkich plików razor w tym samym katalogu i w katalogach podrzędnych.

Jeśli przestrzeń nazw składnika nie znajduje się w zakresie, możesz określić składnik przy użyciu pełnej nazwy typu, jak można to zrobić w języku C#:

<MyComponentLib.Counter />

Modyfikowanie tytułu strony ze składników

Podczas tworzenia aplikacji w stylu SPA typowe jest ponowne ładowanie części strony bez ponownego ładowania całej strony. Mimo to może być przydatne, aby tytuł strony zmienił się w zależności od tego, który składnik jest aktualnie ładowany. Można to osiągnąć, dołączając <PageTitle> tag na stronie Razor składnika:

@page "/"
<PageTitle>Home</PageTitle>

Zawartość tego elementu może być dynamiczna, na przykład pokazującą bieżącą liczbę komunikatów:

<PageTitle>@MessageCount messages</PageTitle>

Należy pamiętać, że jeśli kilka składników na określonej stronie zawiera <PageTitle> tagi, zostaną wyświetlone tylko ostatnie (ponieważ każdy z nich zastąpi poprzednią).

Parametry składników

W ASP.NET web forms można przepływać parametry i dane do kontrolek przy użyciu właściwości publicznych. Te właściwości można ustawić w znacznikach przy użyciu atrybutów lub ustawić bezpośrednio w kodzie. Składniki Razor działają w podobny sposób, chociaż właściwości składnika muszą być również oznaczone atrybutem [Parameter] , który ma być traktowany jako parametry składnika.

Poniższy Counter składnik definiuje parametr składnika o nazwie IncrementAmount , który może służyć do określenia ilości, którą Counter należy zwiększać przy każdym kliknięciu przycisku.

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

Aby określić parametr składnika w pliku Blazor, użyj atrybutu, jak w ASP.NET Web Forms:

<Counter IncrementAmount="10" />

Parametry ciągu zapytania

Składniki Razor mogą również korzystać z wartości z ciągu zapytania strony, na której są renderowane jako źródło parametrów. Aby to włączyć, dodaj [SupplyParameterFromQuery] atrybut do parametru . Na przykład następująca definicja parametru pobierze jego wartość z żądania w formularzu ?IncBy=2:

[Parameter]
[SupplyParameterFromQuery(Name = "IncBy")]
public int IncrementAmount { get; set; } = 1;

Jeśli nie podasz niestandardowego Name w atrybucie [SupplyParameterFromQuery] , domyślnie będzie ona zgodna z nazwą właściwości (IncrementAmount w tym przypadku).

Składniki i granice błędów

Domyślnie Blazor aplikacje będą wykrywać nieobsługiwane wyjątki i wyświetlać komunikat o błędzie w dolnej części strony bez dodatkowych szczegółów. Aby ograniczyć części aplikacji, na które ma wpływ nieobsługiwany błąd, na przykład w celu ograniczenia wpływu na pojedynczy składnik, <ErrorBoundary> tag można opakować wokół deklaracji składników.

Aby na przykład chronić przed możliwymi wyjątkami zgłaszanym przez Counter składnik, zadeklaruj go w elemencie <ErrorBoundary> i opcjonalnie określ komunikat do wyświetlenia, jeśli wystąpi wyjątek:

<ErrorBoundary>
    <ChildContent>
        <Counter />
    </ChildContent>
    <ErrorContent>
        Oops! The counter isn't working right now; please try again later.
    </ErrorContent>
</ErrorBoundary>

Jeśli nie musisz określać niestandardowej zawartości błędów, możesz po prostu opakować składnik bezpośrednio:

<ErrorBoundary>
  <Counter />
</ErrorBoundary>

Zostanie wyświetlony komunikat domyślny "Wystąpił błąd". Jeśli w opakowanym składniku wystąpi nieobsługiwany wyjątek.

Procedury obsługi zdarzeń

Zarówno ASP.NET web forms, jak i Blazor model programowania oparty na zdarzeniach do obsługi zdarzeń interfejsu użytkownika. Przykłady takich zdarzeń obejmują kliknięcia przycisków i wprowadzanie tekstu. W ASP.NET formularzy sieci Web kontrolki serwera HTML służą do obsługi zdarzeń interfejsu użytkownika uwidocznionych przez dom lub można obsługiwać zdarzenia uwidocznione przez kontrolki serwera internetowego. Zdarzenia są udostępniane na serwerze za pośrednictwem żądań po powrocie formularza. Rozważmy następujący przycisk Web Forms kliknij przykład:

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!");
    }
}

W Blazorsystemie można zarejestrować programy obsługi zdarzeń interfejsu użytkownika DOM bezpośrednio przy użyciu atrybutów dyrektywy formularza @on{event}. Symbol {event} zastępczy reprezentuje nazwę zdarzenia. Na przykład możesz nasłuchiwać kliknięć przycisków w następujący sposób:

<button @onclick="OnClick">Click me!</button>

@code {
    void OnClick()
    {
        Console.WriteLine("The button was clicked!");
    }
}

Programy obsługi zdarzeń mogą zaakceptować opcjonalny argument specyficzny dla zdarzenia, aby uzyskać więcej informacji o zdarzeniu. Na przykład zdarzenia myszy mogą przyjmować MouseEventArgs argument, ale nie jest to wymagane.

<button @onclick="OnClick">Click me!</button>

@code {
    void OnClick(MouseEventArgs e)
    {
        Console.WriteLine($"Mouse clicked at {e.ScreenX}, {e.ScreenY}.");
    }
}

Zamiast odwoływać się do grupy metod obsługi zdarzeń, można użyć wyrażenia lambda. Wyrażenie lambda umożliwia zamknięcie innych wartości w zakresie.

@foreach (var buttonLabel in buttonLabels)
{
    <button @onclick="() => Console.WriteLine($"The {buttonLabel} button was clicked!")">@buttonLabel</button>
}

Programy obsługi zdarzeń mogą być wykonywane synchronicznie lub asynchronicznie. Na przykład następująca OnClick procedura obsługi zdarzeń jest wykonywana asynchronicznie:

<button @onclick="OnClick">Click me!</button>

@code {
    async Task OnClick()
    {
        var result = await Http.GetAsync("api/values");
    }
}

Po obsłużeniu zdarzenia składnik jest renderowany w celu uwzględnienia wszelkich zmian stanu składnika. W przypadku asynchronicznych procedur obsługi zdarzeń składnik jest renderowany natychmiast po zakończeniu wykonywania programu obsługi. Składnik jest renderowany ponownie po zakończeniu asynchronicznego Task . Ten asynchroniczny tryb wykonywania zapewnia możliwość renderowania odpowiedniego interfejsu użytkownika, podczas gdy asynchroniczny Task jest nadal w toku.

<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();
    }
}

Składniki mogą również definiować własne zdarzenia, definiując parametr składnika typu EventCallback<TValue>. Wywołania zwrotne zdarzeń obsługują wszystkie odmiany procedur obsługi zdarzeń interfejsu użytkownika DOM: opcjonalne argumenty, synchroniczne lub asynchroniczne, grupy metod lub wyrażenia lambda.

<button class="btn btn-primary" @onclick="OnClick">Click me!</button>

@code {
    [Parameter]
    public EventCallback<MouseEventArgs> OnClick { get; set; }
}

Powiązanie danych

Blazor Udostępnia prosty mechanizm powiązania danych ze składnika interfejsu użytkownika ze stanem składnika. Takie podejście różni się od funkcji ASP.NET Web Forms w celu powiązania danych ze źródeł danych do kontrolek interfejsu użytkownika. Omówimy obsługę danych z różnych źródeł danych w sekcji Obsługa danych .

Aby utworzyć dwukierunkowe powiązanie danych ze składnika interfejsu użytkownika do stanu składnika, użyj atrybutu @bind dyrektywy. W poniższym przykładzie wartość pola wyboru jest powiązana z polem isChecked .

<input type="checkbox" @bind="isChecked" />

@code {
    bool isChecked;
}

Gdy składnik jest renderowany, wartość pola wyboru jest ustawiona na wartość isChecked pola . Gdy użytkownik przełącza pole wyboru, onchange zdarzenie zostanie wyzwolone, a isChecked pole zostanie ustawione na nową wartość. Składnia @bind w tym przypadku jest równoważna następującemu znacznikowi:

<input value="@isChecked" @onchange="(UIChangeEventArgs e) => isChecked = e.Value" />

Aby zmienić zdarzenie używane dla powiązania, użyj atrybutu @bind:event .

<input @bind="text" @bind:event="oninput" />
<p>@text</p>

@code {
    string text;
}

Składniki mogą również obsługiwać powiązanie danych z ich parametrami. Aby powiązać dane, zdefiniuj parametr wywołania zwrotnego zdarzeń o tej samej nazwie co parametr możliwy do powiązania. Sufiks "Zmieniono" jest dodawany do nazwy.

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);
    }
}

Aby połączyć powiązanie danych z bazowym elementem interfejsu użytkownika, ustaw wartość i obsłuż zdarzenie bezpośrednio w elemecie interfejsu użytkownika zamiast przy użyciu atrybutu @bind .

Aby powiązać z parametrem @bind-{Parameter} składnika, użyj atrybutu, aby określić parametr, z którym chcesz powiązać.

<PasswordBox @bind-Password="password" />

@code {
    string password;
}

Zmiany stanu

Jeśli stan składnika zmienił się poza normalnym zdarzeniem interfejsu użytkownika lub wywołaniem zwrotnym zdarzeń, składnik musi ręcznie zasygnalizować, że musi zostać ponownie renderowany. Aby zasygnalizować, że stan składnika uległ zmianie, wywołaj metodę StateHasChanged w składniku.

W poniższym przykładzie składnik wyświetla komunikat z AppState usługi, który może zostać zaktualizowany przez inne części aplikacji. Składnik rejestruje swoją StateHasChanged metodę ze zdarzeniem AppState.OnChange , aby składnik był renderowany za każdym razem, gdy komunikat zostanie zaktualizowany.

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
    }
}

Cykl życia składnika

Platforma ASP.NET Web Forms ma dobrze zdefiniowane metody cyklu życia dla modułów, stron i kontrolek. Na przykład następująca kontrolka implementuje programy obsługi zdarzeń dla Initzdarzeń , Loadi UnLoad cyklu życia:

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) { ... }
}

Składniki Razor mają również dobrze zdefiniowany cykl życia. Cykl życia składnika może służyć do inicjowania stanu składnika i implementowania zaawansowanych zachowań składników.

BlazorWszystkie metody cyklu życia składników mają wersje synchroniczne i asynchroniczne. Renderowanie składników jest synchroniczne. Nie można uruchomić logiki asynchronicznej w ramach renderowania składnika. Cała logika asynchroniczna musi być wykonywana w ramach async metody cyklu życia.

OnInitialized

Metody OnInitialized i OnInitializedAsync służą do inicjowania składnika. Składnik jest zazwyczaj inicjowany po pierwszym renderowaniu. Po zainicjowaniu składnika może być renderowany wiele razy, zanim zostanie ostatecznie usunięty. Metoda jest podobna OnInitialized Page_Load do zdarzenia na stronach i kontrolkach ASP.NET Web Forms.

protected override void OnInitialized() { ... }
protected override async Task OnInitializedAsync() { await ... }

OnParametersSet

Metody OnParametersSet i OnParametersSetAsync są wywoływane, gdy składnik otrzymał parametry z elementu nadrzędnego, a wartość jest przypisywana do właściwości. Te metody są wykonywane po zainicjowaniu składnika i za każdym razem, gdy składnik jest renderowany.

protected override void OnParametersSet() { ... }
protected override async Task OnParametersSetAsync() { await ... }

OnAfterRender

Metody OnAfterRender i OnAfterRenderAsync są wywoływane po zakończeniu renderowania składnika. Odwołania do elementów i składników są wypełniane w tym momencie (więcej na temat poniższych pojęć). Interakcyjność z przeglądarką jest włączona w tym momencie. Interakcje z wykonywaniem modelu DOM i języka JavaScript można bezpiecznie przeprowadzić.

protected override void OnAfterRender(bool firstRender)
{
    if (firstRender)
    {
        ...
    }
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await ...
    }
}

OnAfterRender i OnAfterRenderAsync nie są wywoływane podczas prerendering na serwerze.

Parametr firstRender jest true pierwszym renderowaniem składnika. W przeciwnym razie jego wartość to false.

IDisposable

Składniki Razor mogą implementować IDisposable usuwanie zasobów po usunięciu składnika z interfejsu użytkownika. Składnik Razor może implementować IDispose przy użyciu @implements dyrektywy :

@using System
@implements IDisposable

...

@code {
    public void Dispose()
    {
        ...
    }
}

Odwołania do składników przechwytywania

W ASP.NET web forms często manipuluje wystąpieniem kontrolki bezpośrednio w kodzie, odwołując się do jego identyfikatora. W Blazorprogramie można również przechwytywać i manipulować odwołaniem do składnika, chociaż jest to znacznie mniej powszechne.

Aby przechwycić odwołanie do składnika w programie Blazor, użyj atrybutu @ref dyrektywy. Wartość atrybutu powinna być zgodna z nazwą pola settable o tym samym typie co składnik, do którego odwołuje się odwołanie.

<MyLoginDialog @ref="loginDialog" ... />

@code {
    MyLoginDialog loginDialog = default!;

    void OnSomething()
    {
        loginDialog.Show();
    }
}

Gdy składnik nadrzędny jest renderowany, pole jest wypełniane wystąpieniem składnika podrzędnego. Następnie można wywołać metody w wystąpieniu składnika lub w inny sposób manipulować.

Manipulowanie stanem składnika bezpośrednio przy użyciu odwołań do składników nie jest zalecane. Dzięki temu składnik nie jest renderowany automatycznie w poprawnych godzinach.

Odwołania do elementu przechwytywania

Składniki Razor mogą przechwytywać odwołania do elementu. W przeciwieństwie do kontrolek serwera HTML w ASP.NET Web Forms nie można manipulować dom bezpośrednio przy użyciu odwołania do elementu w programie Blazor. Blazor obsługuje większość interakcji MODELU DOM przy użyciu algorytmu różnicowania MODELU DOM. Przechwycone odwołania do elementów w elemencie Blazor są nieprzezroczyste. Są one jednak używane do przekazywania określonego odwołania do elementu w wywołaniu międzyoperacyjnym języka JavaScript. Aby uzyskać więcej informacji na temat międzyoperacji języka JavaScript, zobacz ASP.NET Core Blazor JavaScript interop.

Składniki z szablonami

W ASP.NET formularzy sieci Web można utworzyć kontrolki szablonowe. Kontrolki szablonowe umożliwiają deweloperowi określenie części kodu HTML używanego do renderowania kontrolki kontenera. Mechanika tworzenia szablonowych kontrolek serwera jest złożona, ale umożliwiają zaawansowane scenariusze renderowania danych w możliwy do dostosowania przez użytkownika sposób. Przykłady kontrolek szablonów to Repeater i DataList.

Składniki Razor można również szablonować, definiując parametry składnika typu RenderFragment lub RenderFragment<T>. Element RenderFragment reprezentuje fragment znaczników Razor, który następnie może być renderowany przez składnik. A RenderFragment<T> to fragment znaczników Razor, który przyjmuje parametr, który można określić podczas renderowania fragmentu renderowania.

Zawartość podrzędna

Składniki Razor mogą przechwytywać zawartość podrzędną RenderFragment jako zawartość i renderować ją w ramach renderowania składnika. Aby przechwycić zawartość podrzędną, zdefiniuj parametr składnika typu RenderFragment i nadaj mu ChildContentnazwę .

ChildContentComponent.razor

<h1>Component with child content</h1>

<div>@ChildContent</div>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
}

Składnik nadrzędny może następnie dostarczać zawartość podrzędną przy użyciu normalnej składni Razor.

<ChildContentComponent>
    <ChildContent>
        <p>The time is @DateTime.Now</p>
    </ChildContent>
</ChildContentComponent>

Parametry szablonu

Szablonowy składnik Razor może również definiować wiele parametrów składnika typu RenderFragment lub RenderFragment<T>. Parametr dla elementu RenderFragment<T> można określić po wywołaniu. Aby określić ogólny parametr typu dla składnika, użyj @typeparam dyrektywy Razor.

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

W przypadku korzystania ze składnika szablonu parametry szablonu można określić przy użyciu elementów podrzędnych, które są zgodne z nazwami parametrów. Argumenty składników typu RenderFragment<T> przekazywane jako elementy mają niejawny parametr o nazwie context. Nazwę tego parametru implementowania można zmienić przy użyciu atrybutu Context w elemecie podrzędnym. Dowolnego parametru typu ogólnego można określić przy użyciu atrybutu zgodnego z nazwą parametru typu. Parametr typu zostanie wywnioskowany, jeśli to możliwe:

<SimpleListView Items="messages" TItem="string">
    <Heading>
        <h1>My list</h1>
    </Heading>
    <ItemTemplate Context="message">
        <p>The message is: @message</p>
    </ItemTemplate>
</SimpleListView>

Dane wyjściowe tego składnika wyglądają następująco:

<h1>My list</h1>
<ul>
    <li><p>The message is: message1</p></li>
    <li><p>The message is: message2</p></li>
<ul>

Plik codebehind

Składnik Razor jest zwykle utworzony w jednym pliku razor . Można jednak również oddzielić kod i znaczniki przy użyciu pliku za pomocą kodu. Aby użyć pliku składnika, dodaj plik C#, który jest zgodny z nazwą pliku składnika, ale z dodanym rozszerzeniem .cs (Counter.razor.cs). Użyj pliku C#, aby zdefiniować klasę bazową dla składnika. Możesz nazwać klasę bazową wszystkimi, co chcesz, ale jest ona pospolita, aby nazwać klasę taką samą jak klasa składnika, ale z dodanym Base rozszerzeniem (CounterBase). Klasa oparta na składnikach musi również pochodzić z klasy ComponentBase. Następnie w pliku składnika Razor dodaj dyrektywę, aby określić klasę @inherits bazową składnika (@inherits CounterBase).

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

Widoczność składowych składnika w klasie bazowej musi być protected widoczna dla klasy składników.public

Dodatkowe zasoby

Powyższe nie jest wyczerpującym traktowaniem wszystkich aspektów składników Razor. Aby uzyskać więcej informacji na temat tworzenia i używania składników ASP.NET Core Razor, zobacz dokumentację Blazor .