Wprowadzenie do komponentów w Blazorze

Budowanie aplikacji frontendowych obecnie składa się z układania małych części widoku oraz jego logiki w taki sposób, aby całość była czytelna i możliwie reużywalna. Nie inaczej jest w Blazorze.

Komponenty są jego podstawowymi elementami z których zbudowana jest każda aplikacja. Służą do wyświetlania oraz zarządzania stanem części UI wraz z logiką jaka na niej występuje. Mogą być zagnieżdżane, reużywalne oraz współdzielone między projektami.

Każdy komponent składa się z pliku .razor w którym znajduje się kod C# oraz HTML. Przykładowy komponent:

@inject IUserService userService

<div class="card w-25">
   <div class="card-header font-weight-bold">User Info</div>
   <div class="card-body">
      <div>@User.Id</div>
      <div>@User.UserName</div>
      <div>@User.FirstName</div>
      <div>@User.LastName</div>
      <div>
         <button @onclick="RemoveUser">Remove</button>
      </div>
   </div>
</div>

@code {
   [Parameter]
   public User User { get; set; }

   public void RemoveUser() {
      userService.Remove(User.Id);
   }
}

Kod C# w komponencie musi być poprzedzony znakiem @ lub sekcja @code, pozostałe części komponentu traktowane są jako tagi HTML. Sekcja @code służy do opisywania logiki, która jest wykonywana w komponencie. Wszystkie zadeklarowane pola będą dostępne w nim poprzez odwołanie się jako @nazwa_pola, dodatkowo możemy obsłużyć zdarzenia takie jak @onclick w danym tagu poprzez napisanie metody oraz podanie jej nazwy jako wartość @onclick. Pola posiadające accessory get i set wymuszają ponowne narysowanie komponentu przy zmianie wartości, natomiast oznaczenie pola atrybutem [Parameter] mogą być przekazywane z komponentu rodzina do dziecka. Przykładowy kod komponentu rodzica:

@inject IUserService userService

<div>
   @foreach(var user in users) 
   {
      <UserInfo User="@user" />
   }
</div>

@code {
   private IList<User> users;

   protected override async Task OnInitializedAsync()
   {
      users = userService.GetAll();
   }
}

W komponencie Users tworzone są komponenty UserInfo do których przekazywany jest parametr User z obiektem użytkownika na podstawie którego później następuje wyświetlenie danych.

Lista użytkowników ładowana jest w specjalnej metodzie, która uruchamiana jest w momencie tworzenia komponentu. Jest to jedna z metod powiązanych z cyklem życia komponentu. Oto schemat obrazujący cykl życia komponentu:

Źródło: Lifecycle events, docs.microsoft.com

Podczas tworzenia komponentu, gdy zostają w nim ustawiane parametry wywoływana jest metoda SetParametersAsync, następnie, gdy jest już zainicjalizowany wywoływane są metody OnInitialized i OnInitializedAsync. Po samym narysowaniu komponentu mamy jeszcze metodę OnAfterRender oraz jej asynchroniczną wersje OnAfterRenderAsync. Jeżeli chcemy na podstawie parametrów ustawić stan komponentu to metoda OnInitialized jest odpowiednim miejscem, natomiast w sytuacji, gdy chcemy aktualizować wewnętrzny stan komponentu po każdej zmianie parametru z zewnątrz powinniśmy użyć metody OnParametersSet.

Komponenty Users i UserInfo korzystają z zewnętrznego serwisu implementujacego interfejs IUserService. Jest to możliwe przy wykorzystaniu dyrektywy @inject, która pozwala na wstrzykniecie serwisu zarejestrowanego podczas tworzenia aplikacji w Program.cs. Nie jest to jedyna dyrektywa, która pozwala na rozszerzanie działania komponentu. Inne dyrektywy to:

NazwaWykorzystanieOpis
page@page „/user/{id}”Ustawia ścieżkę routing do komponentu poprzez którą możliwe jest wyświetlenie go pod endpointem /user/{id}
implements@implements IDisposablePozwala na implementowanie interfejsu w komponencie, w tym przypadku na utworzenie komponentu, który może być disposable.
inherits@inherits ComponentBaseUmożliwia dziedziczenie komponentów, dyrektywa jest przydatna, gdy chcemy współdzielić wspólne cechy komponentów.
typeparam@typeparam TItemOdpowiednik typów generycznych dla komponentów. Możliwe jest utworzenie komponentu, który będzie miał te same zachowanie dla kilku różnych typów.
using@using System.LinqUmożliwia odwolywanie się do elementów z podanej przestrzeni nazw w tym wypadku System.Linq bez podawania pełnej ścieżki. Alternatywnie można użyć tej dyrektywy w _Imports.razor, aby zastosować ją globalnie.
layout@layout MainLayoutUstawienie layoutu w jakim ma renderować się komponent, w tym wypadku będzie to MainLayout. Komponenty layoutów muszą dziedziczyć z LayoutComponentBase.
attribute@attribute [Authorize]Pozwala na ustawienie atrybutu dla komponentu. Przykładowym atrybutem może być Authorize bądź AllowAnonymous.

Przedstawiłem podstawowe informacje o komponentach, dodatkowo warto dokładniej przyjrzeć się temu w którym momencie występuje odrysowanie komponentu i jak możemy nim sterować oraz jak zwracać informacje o zaistnieniu zdarzenia poprzez interfejs EventCallback<T>. Pamiętaj, że podział na komponenty jest równie ważny, zachęcam do zapoznania się z wpisem jak ja to robię, aby uniknąć późniejszych problemów.

Jeżeli uznasz ten post za przydatny to proszę udostępnij go innym, natomiast jak chcesz być na bieżąco i otrzymywać informacje o moich aktywnościach przed innymi to zapraszam Cię do newslettera na którym regularnie udostępniam przedpremierowo artykuły, materiały wideo i wiele więcej.

Share via
Copy link
Powered by Social Snap