Bagikan melalui


Membangun komponen antarmuka pengguna yang dapat digunakan kembali dengan Blazor

Petunjuk / Saran

Konten ini adalah kutipan dari eBook, Blazor untuk Pengembang ASP NET Web Forms untuk Azure, tersedia di .NET Docs atau sebagai PDF yang dapat diunduh gratis dan dapat dibaca secara offline.

Blazor-for-ASP-NET-Web-Forms-Developers gambar mini sampul eBook.

Salah satu hal indah tentang ASP.NET Web Forms adalah bagaimana kerangka kerja tersebut memungkinkan enkapsulasi potongan kode antarmuka pengguna yang dapat digunakan kembali ke dalam kontrol antarmuka pengguna yang dapat digunakan kembali. Kontrol pengguna kustom dapat ditentukan dalam markup dengan menggunakan file .ascx. Anda juga dapat membangun kontrol server yang terperinci dalam kode dengan dukungan penuh desainer.

Blazor juga mendukung enkapulasi antarmuka pengguna melalui komponen. Sebuah komponen:

  • Merupakan potongan antarmuka pengguna yang mandiri.
  • Mempertahankan status dan logika penyajiannya sendiri.
  • Dapat menentukan penanganan aktivitas antarmuka pengguna, mengikat ke data input, dan mengelola siklus hidupnya sendiri.
  • Biasanya didefinisikan dalam file .razor dengan menggunakan sintaks Razor.

Pengantar Razor

Razor adalah bahasa pemrograman pembuatan templat markup yang ringan berdasarkan HTML dan C#. Dengan Razor, Anda dapat dengan mulus bertransisi antara markup dan kode C# untuk menentukan logika pe-render-an komponen Anda. Saat file .razor dikompilasi, logika pe-render-an diambil dengan cara terstruktur di kelas .NET. Nama kelas yang dikompilasi diambil dari nama file .razor. Namespace diambil dari namespace default untuk proyek dan jalur folder, atau Anda dapat menentukan namespace secara eksplisit dengan menggunakan arahan @namespace (selengkapnya tentang arahan Razor di bawah).

Logika pe-render-an komponen ditulis menggunakan markup HTML normal dengan logika dinamis yang ditambahkan menggunakan C#. Karakter @ digunakan untuk bertransisi ke C#. Biasanya, Razor pintar dalam mencari tahu kapan Anda telah beralih kembali ke HTML. Misalnya, komponen berikut me-render tag <p> dengan waktu saat ini:

<p>@DateTime.Now</p>

Untuk secara eksplisit menentukan awal dan akhir ekspresi C#, gunakan tanda kurung:

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

Razor juga mempermudah penggunaan alur kontrol C# dalam logika pe-render-an Anda. Misalnya, Anda dapat me-render beberapa HTML secara kondisional seperti ini:

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

Anda juga dapat membuat daftar item menggunakan perulangan C# foreach normal seperti ini:

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

Arahan Razor, seperti arahan dalam ASP.NET Web Forms, mengontrol banyak aspek tentang bagaimana komponen Razor dikompilasi. Contoh-contohnya termasuk komponen:

  • Ruang nama
  • Kelas dasar
  • Antarmuka yang diimplementasikan
  • Parameter umum
  • Namespace yang diimpor
  • Rute

Arahan Razor biasanya dimulai dengan karakter @ dan biasanya digunakan di awal baris baru atau di awal file. Misalnya, arahan @namespace menentukan namespace komponen:

@namespace MyComponentNamespace

Tabel berikut merangkum berbagai arahan Razor yang digunakan di Blazor dan yang setara dengan ASP.NET Web Forms, jika ada.

Direktif Deskripsi Contoh Setara dengan Web Forms
@attribute Menambahkan atribut tingkat kelas ke komponen @attribute [Authorize] Tidak
@code Menambahkan anggota kelas ke komponen @code { ... } <script runat="server">...</script>
@implements Mengimplementasikan antarmuka yang ditentukan @implements IDisposable Menggunakan code-behind
@inherits Mewarisi dari kelas dasar yang ditentukan @inherits MyComponentBase <%@ Control Inherits="MyUserControlBase" %>
@inject Menyuntikkan layanan ke dalam komponen @inject IJSRuntime JS Tidak
@layout Menentukan komponen tata letak untuk komponen @layout MainLayout <%@ Page MasterPageFile="~/Site.Master" %>
@namespace Mengatur namespace untuk komponen @namespace MyNamespace Tidak
@page Menentukan rute untuk komponen @page "/product/{id}" <%@ Page %>
@typeparam Menentukan parameter jenis generik untuk komponen @typeparam TItem Menggunakan code-behind
@using Menentukan namespace yang akan dibawa ke cakupan @using MyComponentNamespace Menambahkan namespace di web.config

Komponen razor juga menggunakan atribut direktif yang luas pada elemen untuk mengontrol berbagai aspek bagaimana komponen dikompilasi (penanganan peristiwa, pengikatan data, referensi komponen & elemen, dan sebagainya). Semua atribut arahan mengikuti sintaks generik umum di mana nilai dalam tanda kurung bersifat opsional:

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

Tabel berikut merangkum berbagai atribut untuk arahan Razor yang digunakan di Blazor.

Atribut Deskripsi Contoh
@attributes Me-render kamus atribut <input @attributes="ExtraAttributes" />
@bind Membuat pengikatan data dua arah <input @bind="username" @bind:event="oninput" />
@on{event} Menambahkan penanganan aktivitas untuk kejadian yang telah ditentukan <button @onclick="IncrementCount">Click me!</button>
@key Menentukan kunci yang akan digunakan oleh algoritma diffing untuk mempertahankan elemen dalam koleksi <DetailsEditor @key="person" Details="person.Details" />
@ref Mengambil referensi ke komponen atau elemen HTML <MyDialog @ref="myDialog" />

Berbagai atribut arahan yang digunakan oleh Blazor (@onclick, @bind, @ref, dan sebagainya) di bahas dalam bagian di bawah ini dan bab-bab selanjutnya.

Banyak sintaks yang digunakan dalam file .aspx dan .ascx memiliki sintaks paralel di Razor. Di bawah ini adalah perbandingan sederhana dari sintaks untuk ASP.NET Web Forms dan Razor.

Fitur Formulir Web Sintaks Pisau cukur Sintaks
Arahan <%@ [directive] %> <%@ Page %> @[directive] @page
Blok kode <% %> <% int x = 123; %> @{ } @{ int x = 123; }
Ekspresi
(HTML-dikodekan)
<%: %> <%:DateTime.Now %> Implisit: @
Eksplisit: @()
@DateTime.Now
@(DateTime.Now)
Komentar <%-- --%> <%-- Commented --%> @* *@ @* Commented *@
Pengikatan data <%# %> <%# Bind("Name") %> @bind <input @bind="username" />

Untuk menambahkan anggota ke kelas komponen Razor, gunakan arahan @code. Teknik ini mirip dengan menggunakan blok <script runat="server">...</script> di kontrol pengguna atau halaman ASP.NET Web Forms.

@code {
    int count = 0;

    void IncrementCount()
    {
        count++;
    }
}

Karena Razor didasarkan pada C#, Razor harus dikompilasi dari dalam proyek C# (.csproj). Anda tidak dapat mengompilasi file .razor dari proyek Visual Basic (.vbproj). Anda masih dapat mereferensikan proyek Visual Basic dari proyek Blazor Anda. Hal yang sebaliknya juga benar.

Untuk referensi lengkap sintaks Razor, lihat referensi sintaks Razor untuk ASP.NET Core.

Menggunakan komponen

Selain HTML biasa, komponen juga dapat menggunakan komponen lain sebagai bagian logika pe-render-an. Sintaks untuk menggunakan sebuah komponen di Razor mirip dengan sintaks untuk menggunakan kontrol pengguna di aplikasi ASP.NET Web Forms. Komponen ditentukan dengan menggunakan tag elemen yang cocok dengan nama jenis komponen. Misalnya, Anda dapat menambahkan komponen Counter seperti ini:

<Counter />

Tidak seperti ASP.NET Web Forms, komponen di Blazor:

  • Tidak menggunakan prefiks elemen (misalnya, asp:).
  • Tidak membutuhkan pendaftaran di halaman atau di web.config.

Pikirkan komponen Razor seperti bagaimana Anda memikirkan jenis .NET, karena itulah mereka. Jika rakitan yang berisi komponen direferensikan, komponen tersebut tersedia untuk digunakan. Untuk membawa namespace komponen ke dalam cakupan, terapkan arahan @using:

@using MyComponentLib

<Counter />

Seperti yang terlihat dalam proyek Blazor default, menempatkan arahan @using ke dalam file _Imports.razor merupakan hal yang umum dilakukan, sehingga arahan tersebut diimpor ke semua file .razor di direktori yang sama dan di direktori turunan.

Jika namespace untuk sebuah komponen tidak ada dalam cakupan, Anda dapat menentukan komponen dengan menggunakan nama jenis lengkapnya, seperti yang dapat Anda lakukan di C#:

<MyComponentLib.Counter />

Mengubah judul halaman dari komponen

Saat membangun aplikasi bergaya SPA, memuat ulang sebagian halaman tanpa memuat ulang seluruh halaman merupakan hal yang umum terjadi. Meskipun demikian, akan berguna untuk mengubah judul halaman berdasarkan komponen mana yang sedang dimuat. Hal ini dapat dicapai dengan menyertakan tag <PageTitle> di halaman Razor komponen:

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

Konten elemen ini dapat bersifat dinamis, misalnya menunjukkan jumlah pesan saat ini:

<PageTitle>@MessageCount messages</PageTitle>

Perhatikan bahwa jika beberapa komponen pada halaman tertentu menyertakan tag <PageTitle>, hanya yang terakhir yang akan ditampilkan (karena setiap komponen akan menimpa yang sebelumnya).

Parameter komponen

Di ASP.NET Web Forms, Anda dapat mengalirkan parameter dan data ke kontrol dengan menggunakan properti publik. Properti ini dapat diatur dalam markup menggunakan atribut atau diatur secara langsung dalam kode. Komponen Razor bekerja dengan cara yang serupa, meskipun properti komponen juga harus ditandai dengan atribut [Parameter] agar dapat dianggap sebagai parameter komponen.

Komponen Counter berikut mendefinisikan sebuah parameter komponen yang disebut IncrementAmount yang dapat digunakan untuk menentukan jumlah yang harus dinaikkan oleh Counter setiap kali tombol diklik.

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

Untuk menentukan parameter komponen dalam Blazor, gunakan atribut seperti yang Anda lakukan di ASP.NET Web Forms:

<Counter IncrementAmount="10" />

Parameter untai kueri

Komponen Razor juga dapat memanfaatkan nilai dari string kueri halaman tempat mereka di-render sebagai sumber parameter. Untuk mengaktifkannya, tambahkan atribut [SupplyParameterFromQuery] ke parameter. Misalnya, definisi parameter berikut akan mendapatkan nilainya dari permintaan dalam formulir ?IncBy=2:

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

Jika Anda tidak memberikan Name kustom dalam atribut [SupplyParameterFromQuery], secara default atribut tersebut akan cocok dengan nama properti (dalam hal ini IncrementAmount).

Komponen dan batas kesalahan

Secara default, aplikasi Blazor akan mendeteksi pengecualian tak tertangani dan menampilkan pesan kesalahan di bagian bawah halaman tanpa detail tambahan. Untuk membatasi bagian-bagian aplikasi yang terpengaruh oleh kesalahan tak tertangani, misalnya untuk membatasi dampak pada satu komponen, tag <ErrorBoundary> dapat membungkus sekitar deklarasi komponen.

Misalnya, untuk melindungi dari kemungkinan pengecualian yang dilemparkan dari komponen Counter, deklarasikan komponen dalam <ErrorBoundary> dan secara opsional, tentukan pesan untuk ditampilkan jika ada pengecualian:

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

Jika Anda tidak perlu menentukan konten kesalahan kustom, Anda dapat langsung membungkus komponen secara langsung:

<ErrorBoundary>
  <Counter />
</ErrorBoundary>

Sebuah pesan default yang menyatakan "Terjadi kesalahan." akan ditampilkan jika terjadi pengecualian tak tertangani dalam komponen yang dibungkus.

Penangan kejadian

Baik ASP.NET Web Forms dan Blazor menyediakan model pemrograman berbasis kejadian untuk menangani kejadian antarmuka pengguna. Contoh-contoh kejadian tersebut termasuk klik tombol dan input teks. Di ASP.NET Web Forms, Anda menggunakan kontrol server HTML untuk menangani kejadian UI yang diekspos oleh DOM, atau Anda dapat menangani kejadian yang diekspos oleh kontrol server web. Kejadian-kejadian tersebut muncul di server melalui permintaan posting kembali formulir. Perhatikan contoh klik tombol Web Form berikut:

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

Di Blazor, Anda dapat mendaftarkan penangan untuk kejadian antarmuka pengguna DOM secara langsung dengan menggunakan atribut arahan dari formulir @on{event}. Tempat penampung {event} mewakili nama kejadian. Misalnya, Anda dapat mendengarkan klik tombol seperti ini:

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

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

Penanganan aktivitas dapat menerima argumen opsional khusus kejadian untuk memberikan informasi selengkapnya tentang kejadian tersebut. Misalnya, kejadian mouse dapat mengambil argumen MouseEventArgs, tetapi tidak diharuskan.

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

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

Alih-alih merujuk ke sebuah grup metode untuk penanganan aktivitas, Anda dapat menggunakan ekspresi lambda. Ekspresi lambda memungkinkan Anda untuk menutup nilai dalam cakupan lainnya.

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

penanganan aktivitas dapat berjalan secara sinkron atau asinkron. Misalnya, penanganan aktivitas OnClick berikut berjalan secara asinkron:

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

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

Setelah sebuah kejadian ditangani, komponen tersebut di-render untuk memperhitungkan setiap perubahan status komponen. Dengan penanganan kejadian asinkron, komponen di-render segera setelah eksekusi penanganan selesai. Komponen tersebut di-render lagi setelah Task asinkron selesai. Mode eksekusi asinkron ini memberikan kesempatan untuk me-render beberapa antarmuka pengguna yang sesuai saat Task masih berlangsung.

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

Komponen juga dapat menentukan kejadian mereka sendiri dengan mendefinisikan parameter komponen jenis EventCallback<TValue>. Panggilan balik kejadian mendukung semua variasi penanganan aktivitas antarmuka pengguna DOM: argumen opsional, sinkron atau asinkron, grup metode, atau ekspresi lambda.

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

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

Pengikatan data

Blazor menyediakan mekanisme sederhana untuk mengikat data dari sebuah komponen antarmuka pengguna ke status komponen. Pendekatan ini berbeda dari fitur di ASP.NET Web Forms untuk mengikat data dari sumber data ke kontrol antarmuka pengguna. Kami akan membahas penanganan data dari sumber data yang berbeda di bagian Menangani data.

Untuk membuat pengikatan data dua arah dari komponen antarmuka pengguna ke status komponen, gunakan atribut arahan @bind. Dalam contoh berikut, nilai kotak centang terikat ke bidang isChecked.

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

@code {
    bool isChecked;
}

Saat komponen tersebut dirender, nilai kotak centang ditetapkan ke nilai bidang isChecked. Saat pengguna mengalihkan kotak centang, kejadian onchange diaktifkan dan bidang isChecked ditetapkan ke nilai yang baru. Dalam hal ini, sintaks @bind setara dengan markup berikut:

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

Untuk mengubah kejadian yang digunakan untuk ikatan, gunakan atribut @bind:event.

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

@code {
    string text;
}

Komponen juga dapat mendukung pengikatan data ke parameternya. Untuk pengikatan data, tentukan parameter panggilan balik kejadian dengan nama yang sama dengan parameter yang dapat diikat. Akhiran "Changed" ditambahkan ke nama.

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

Untuk menautkan pengikatan data ke elemen antarmuka pengguna yang mendasar, tentukan nilai dan tangani kejadian secara langsung pada elemen antarmuka pengguna, alih-alih menggunakan atribut @bind.

Untuk mengikat parameter komponen, gunakan atribut @bind-{Parameter} untuk menentukan parameter yang ingin Anda ikat.

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

@code {
    string password;
}

Status Perubahan

Jika status komponen telah berubah di luar kejadian antarmuka pengguna atau panggilan balik kejadian normal, komponen harus memberi sinyal secara manual bahwa komponen tersebut perlu di-render lagi. Untuk memberi sinyal bahwa status komponen telah berubah, panggil metode StateHasChanged pada komponen.

Dalam contoh di bawah, sebuah komponen menampilkan pesan dari layanan AppState yang dapat diperbarui oleh bagian-bagian lain dari aplikasi. Komponen tersebut mendaftarkan metode StateHasChanged-nya dengan kejadian AppState.OnChange, sehingga komponen tersebut di-render setiap kali pesan diperbarui.

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

Siklus hidup komponen

Kerangka kerja ASP.NET Web Forms memiliki metode siklus hidup yang dirumuskan dengan baik untuk modul, halaman, dan kontrol. Misalnya, kontrol berikut mengimplementasikan penanganan aktivitas untuk kejadian siklus hidup Init, Load, dan UnLoad:

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

Komponen Blazor juga memiliki siklus hidup yang dirumuskan dengan baik. Siklus hidup sebuah komponen dapat digunakan untuk menginisialisasi status komponen dan mengimplementasikan perilaku komponen tingkat lanjut.

Semua metode siklus hidup komponen Blazor memiliki versi sinkron dan asinkron. Pe-render-an komponen bersifat sinkron. Anda tidak dapat menjalankan logika asinkron sebagai bagian dari pe-render-an komponen. Semua logika asinkron harus dijalankan sebagai bagian dari metode siklus hidup async.

OnInitialized

Metode OnInitialized dan OnInitializedAsync digunakan untuk menginisialisasi komponen. Biasanya, sebuah komponen diinisialisasi setelah pertama kali dirender. Setelah sebuah komponen diinisialisasi, komponen tersebut dapat di-render beberapa kali sebelum akhirnya dibuang. Metode OnInitialized mirip dengan kejadian Page_Load di halaman dan kontrol ASP.NET Web Forms.

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

OnParametersSet

Metode OnParametersSet dan OnParametersSetAsync dipanggil ketika sebuah komponen telah menerima parameter dari induknya dan nilai ditetapkan ke properti. Metode-metode ini dijalankan setelah inisialisasi komponen dan setiap kali komponen di-render.

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

OnAfterRender

Metode OnAfterRender dan OnAfterRenderAsync dipanggil setelah komponen selesai di-render. Pada titik ini, elemen dan komponen diisi (selengkapnya tentang konsep-konsep ini di bawah). Interaktivitas dengan browser diaktifkan pada titik ini. Interaksi dengan eksekusi DOM dan JavaScript dapat berlangsung dengan aman.

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

OnAfterRender dan OnAfterRenderAsynctidak dipanggil saat melakukan pra-penyajian di server.

Parameter firstRender bernilai true saat pertama kali komponen di-render; selain itu, nilainya adalah false.

IDisposable

Komponen Razor dapat mengimplementasikan IDisposable untuk membuang sumber daya ketika komponen dihapus dari antarmuka pengguna. Sebuah komponen Razor dapat mengimplementasikan IDispose dengan menggunakan arahan @implements:

@using System
@implements IDisposable

...

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

Mengambil referensi komponen

Di ASP.NET Web Forms, memanipulasi instans kontrol secara langsung dalam kode dengan merujuk ke ID-nya merupakan hal yang umum dilakukan. Di Blazor, mengambil dan memanipulasi referensi ke komponen juga dapat dilakukan, meskipun lebih jarang terjadi.

Untuk mengambil referensi komponen di Blazor, gunakan atribut arahan @ref. Nilai atribut harus cocok dengan nama bidang yang dapat diatur, yang memiliki jenis yang sama dengan komponen yang direferensikan.

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

@code {
    MyLoginDialog loginDialog = default!;

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

Saat komponen induk di-render, bidang diisi dengan instans komponen turunan. Kemudian, Anda dapat memanggil metode atau memanipulasi instans komponen.

Memanipulasi status komponen secara langsung dengan menggunakan referensi komponen tidak direkomendasikan. Melakukan hal tersebut mencegah komponen di-render secara otomatis pada waktu yang tepat.

Mengambil referensi elemen

Komponen Razor dapat mengambil referensi ke suatu elemen. Tidak seperti kontrol server HTML di ASP.NET Web Forms, Anda tidak dapat memanipulasi DOM secara langsung menggunakan referensi elemen di Blazor. Blazor menangani sebagian besar interaksi DOM untuk Anda menggunakan algoritma diffing DOM. Referensi elemen yang diambil di Blazor buram. Namun, referensi elemen tersebut digunakan untuk meneruskan referensi elemen khusus dalam panggilan JavaScript interop. Untuk informasi selengkapnya tentang JavaScript interop, lihat ASP.NET Core Blazor JavaScript interop.

Komponen bertemplat

Di ASP.NET Web Forms, Anda dapat membuat kontrol bertemplat. Kontrol bertemplat memungkinkan developer untuk menentukan bagian HTML yang digunakan untuk merender kontrol kontainer. Mekanisme pembangunan kontrol server bertemplat rumit, tetapi mekanisme tersebut mengaktifkan skenario yang kuat untuk merender data dengan cara yang dapat disesuaikan pengguna. Contoh-contoh kontrol bertemplat termasuk Repeater dan DataList.

Komponen Razor juga dapat di-templat dengan mendefinisikan parameter komponen jenis RenderFragment atau RenderFragment<T>. RenderFragment mewakili potongan markup Razor yang dapat di-render oleh komponen. RenderFragment<T> adalah potongan markup Razor yang mengambil parameter yang dapat ditentukan saat fragmen render di-render.

Konten turunan

Komponen-komponen Razor dapat mengambil konten turunan mereka sebagai RenderFragment dan merender konten itu sebagai bagian dari pe-render-an komponen. Untuk mengambil konten turunan, tentukan parameter komponen jenis RenderFragment dan beri nama ChildContent.

ChildContentComponent.razor

<h1>Component with child content</h1>

<div>@ChildContent</div>

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

Kemudian, komponen induk dapat menyediakan konten turunan dengan menggunakan sintaks Razor normal.

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

Parameter template

Komponen Razor bertemplat juga dapat menentukan beberapa parameter komponen jenis RenderFragment atau RenderFragment<T>. Parameter untuk RenderFragment<T> dapat ditentukan saat dipanggil. Untuk menentukan parameter jenis generik untuk sebuah komponen, gunakan arahan Razor @typeparam.

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

Saat menggunakan komponen bertemplat, parameter templat dapat ditentukan dengan menggunakan elemen turunan yang cocok dengan nama parameter. Argumen komponen jenis RenderFragment<T> yang diteruskan sebagai elemen memiliki parameter implisit bernama context. Anda dapat mengubah nama parameter implement ini dengan menggunakan atribut Context pada elemen turunan. Parameter jenis generik apa pun dapat ditentukan dengan menggunakan atribut yang cocok dengan nama parameter jenis. Parameter jenis akan disimpulkan jika memungkinkan:

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

Output dari komponen ini terlihat seperti ini:

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

Kode di belakang

Komponen Razor biasanya ditulis dalam satu file .razor. Namun, kode dan markup juga dapat dipisahkan dengan menggunakan file code-behind. Untuk menggunakan file komponen, tambahkan file C# yang cocok dengan nama file dari file komponen, tetapi dengan menambahkan ekstensi .cs (Counter.razor.cs). Gunakan file C# untuk menentukan kelas dasar untuk komponen. Anda dapat menamai kelas dasar apa pun yang Anda suka, tetapi biasanya nama kelas memiliki nama yang sama dengan kelas komponen, dengan menambahkan ekstensi Base (CounterBase). Kelas berbasis komponen juga harus diturunkan dari ComponentBase. Kemudian, di file komponen Razor, tambahkan arahan @inherits untuk menentukan kelas dasar untuk komponen (@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++;
    }
}

Visibilitas anggota komponen dalam kelas dasar harus protected atau public agar terlihat oleh kelas komponen.

Sumber Daya Tambahan:

Hal-hal yang dijelaskan di atas bukan merupakan perlakuan lengkap dari semua aspek komponen Razor. Untuk informasi selengkapnya tentang cara Membuat dan menggunakan komponen ASP.NET Core Razor, lihat dokumentasi Blazor.